iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0

GoF對工廠方法模式 (Factory Method) 的解釋是:
「定義一個可以產生物件的介面,但是子類別決定要產生哪一個類別的物件。工廠方法讓類別的實例化程序延遲到子類別中實行」

在這邊還是舉比較容易理解的形狀當作例子,這邊先宣告三種形狀與他對應會繪畫/輸出出的東西。

Shape.cs

using UnityEngine; 

namespace LinXuan.DesignPattern.Example.Factory 
{ 
    public interface IShape 
    { 
        public void Draw(); 
    } 
    
    public class Sphere : IShape 
    { 
        public void Draw() 
        { 
            Debug.Log("Draw sphere."); 
        } 
    }
    
    public class Cube : IShape 
    { 
        public void Draw() 
        { 
            Debug.Log("Draw cube."); 
        } 
    } 
    
    public class Cylinder : IShape 
    { 
        public void Draw() 
        { 
            Debug.Log("Draw cylinder."); 
        } 
    }
    
}

而Factory在依照語言本身擁有的特性去實作,在這邊要舉的第一個例子是Subclass。

Subclass方式


IShapeFactory.cs

namespace LinXuan.DesignPattern.Example.Factory 
{ 
    public interface IShapeFactory 
    { 
        public IShape CreateShape(); 
    } 
}

ShapeFactorys.cs

namespace LinXuan.DesignPattern.Example.Factory 
{ 
    public class SphereFactory : IShapeFactory 
    { 
        public IShape CreateShape() 
        { 
            return new Sphere(); 
        } 
    } 
    
    public class CubeFactory : IShapeFactory 
    { 
        public IShape CreateShape() 
        { 
            return new Cube(); 
        } 
    } 
    
    public class CylinderFactory : IShapeFactory 
    { 
        public IShape CreateShape() 
        { 
            return new Cylinder(); 
        } 
    } 
}

FactorySubclassMethodTest.cs

using UnityEngine; 

namespace LinXuan.DesignPattern.Example.Factory 
{ 
    public class FactorySubclassMethodTest : MonoBehaviour 
    { 
        private void Start() 
        { 
            IShapeFactory shapeFactory = null; 
            IShape shape = null; 
            shapeFactory = new CubeFactory(); 
            shape = shapeFactory.CreateShape(); 
            shape.Draw(); 
            shapeFactory = new CylinderFactory(); 
            shape = shapeFactory.CreateShape(); 
            shape.Draw(); 
            shapeFactory = new SphereFactory(); 
            shape = shapeFactory.CreateShape(); 
            shape.Draw(); 
        } 
    } 
}

輸出如下
https://ithelp.ithome.com.tw/upload/images/20220929/20151894AztDmhnJSt.png

第二種則是MethodType

MethodType方式

ShapeType.cs

namespace LinXuan.DesignPattern.Example.Factory
{
    public enum ShapeType
    {
        Sphere,
        Cube,
        Cylinder
    }
}

ShapeFactory.cs

using UnityEngine; 

namespace LinXuan.DesignPattern.Example.Factory 
{ 
    public class ShapeFactory 
    { 
        public IShape GetShape(ShapeType shapeType) 
        { 
            switch (shapeType) 
            { 
                case ShapeType.Sphere: 
                    return new Sphere(); 
                case ShapeType.Cube: 
                    return new Cube(); 
                case ShapeType.Cylinder: 
                    return new Cylinder(); 
                default: 
                    Debug.LogError("Don't have this shape type."); 
                    return null; 
            } 
        } 
    } 
}

FactoryMethodTypeTest.cs

using UnityEngine; 

namespace LinXuan.DesignPattern.Example.Factory 
{ 
    public class FactoryMethodTypeTest : MonoBehaviour 
    { 
        private void Start() 
        { 
            IShape shape = null; 
            ShapeFactory shapeFactory = new ShapeFactory(); 
            shape = shapeFactory.GetShape(ShapeType.Cube); 
            shape.Draw(); 
            shape = shapeFactory.GetShape(ShapeType.Sphere); 
            shape.Draw(); 
            shape = shapeFactory.GetShape(ShapeType.Cylinder); 
            shape.Draw(); 
        } 
    } 
}

輸出如下
https://ithelp.ithome.com.tw/upload/images/20220929/201518943jQ6O5Y9vO.png

除此之外C#還可以用泛型(Generic)的方式實作,不過Generic這個觀念可能對於剛學架構的人來說比較複雜點,這邊就不打出來了,有興趣可以自己翻閱相關資料。

下一篇會講Factory實際上的應用。

參考資料

設計模式與遊戲開發的完美結合(暢銷回饋版)
tutorialspoint


上一篇
Day 14:Mediator模式
下一篇
Day 16:Factory模式(二)
系列文
如何在Unity裡寫出具有一定擴充性的遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言