簡體   English   中英

我正在研究抽象工廠模式,為 class 的每種類型都有一個抽象工廠是一種好的做法嗎?

[英]I am studying the abstract factory pattern, is it good practice to have an abstract factory for each type of class?

我正在實現抽象工廠模式,有沒有辦法不對不同的 class 類型使用抽象 class?

我的課程結構是這樣的: Structure Project

Rectangle.cs 和 Square.cs 實現 IShape.cs: Structure Class for AbstractShapeFactory

namespace FactoryMethod.Patterns.Creational.Factory.Shape
{
    public interface IShape
    {
        public void Draw();
    }
}
namespace FactoryMethod.Patterns.Creational.Factory.Shape.Normal
{
    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("Normal Rectangle");
        }
    }
}

NormalShapeImp.cs 和 RoundedShapeImp.cs 實現 AbstractShapeFactory.cs

AbstractShapeFactory.cs class 看起來像這樣:

namespace FactoryMethod.Patterns.Creational.Factory
{
    public enum TypeShape
    {
        Square = 1,
        Rectangle = 2
    }

    public abstract class AbstractShapeFactory
    {
        public abstract IShape CreateShape(TypeShape typeShape);
    }
}


public class NormalShapeImp : AbstractShapeFactory
    {
        public override IShape CreateShape(TypeShape typeShape)
        {
            return typeShape switch
            {
                TypeShape.Square => new Square(),
                TypeShape.Rectangle => new Rectangle(),
                _ => new Square(),
            };
        }
    }

AbstractPaymentFactory.cs class 看起來像這樣:

namespace FactoryMethod.Patterns.Creational.Factory
{
    public enum TypePayment
    {
        Google = 1,
        Paypal = 2
    }

    public abstract class AbstractPaymentFactory
    {
        public abstract IPayment CreatePayment(TypePayment typePayment);
    }
}

namespace FactoryMethod.Patterns.Creational.Factory.Payment
{
    public class LocalPaymentImp : AbstractPaymentFactory
    {
        public override IPayment CreatePayment(TypePayment typePayment)
        {
            return typePayment switch
            {
                TypePayment.Google => new LocalGooglePayment(),
                TypePayment.Paypal => new LocalPaypal(),
                _ => new LocalGooglePayment(),
            };
        }
    }
}

我有兩個抽象工廠類 AbstractPaymentFactory.cs Y AbstractShapeFactory.cs

我有一個 FactoryProducer.cs class 負責返回一個或另一個工廠。

namespace FactoryMethod.Patterns.Creational.Factory
{
    public class FactoryProducer
    {
        public static AbstractPaymentFactory GetPaymentFactory(bool isLocal)
        {
            if (isLocal)
                return new LocalPaymentImp();

            return new ForeignPaymentImp();
        }

        public static AbstractShapeFactory GetShapeFactory(bool isRounded)
        {
            if (isRounded)
                return new RoundedShapeImp();

            return new NormalShapeImp();
        }
    }
}

我的 Program.cs class 如下:

static void Main(string[] args)
        {
            #region Pattern Abstract Factory

            /* Factory Payment */
            Console.WriteLine("Factory Payment:");
            Console.WriteLine("Select Type Payment:");
            Console.WriteLine("1- Google (default)");
            Console.WriteLine("2- Paypal");

            int inputType = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("Select Account:");
            Console.WriteLine("0- Local");
            Console.WriteLine("1- Foreign (default)");
            bool opAccount = Console.ReadLine() == "0";

            AbstractPaymentFactory factoryPayment = FactoryProducer.GetPaymentFactory(opAccount);
            IPayment payment = factoryPayment.CreatePayment((TypePayment)inputType);
            payment.DoPayment();
            Console.WriteLine("");

            /* End Factory Payment */


            /* Factory Shape */
            Console.WriteLine("Factory Payment:");
            Console.WriteLine("Select Type Shape");
            Console.WriteLine("1- Square (default)");
            Console.WriteLine("2- Rectangle");

            int inputTypeShape = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("Select:");
            Console.WriteLine("0- Normal (default)");
            Console.WriteLine("1- Rounded");
            bool opShape = Console.ReadLine() == "0";

            AbstractShapeFactory factoryShape = FactoryProducer.GetShapeFactory(opShape);
            IShape shape = factoryShape.CreateShape((TypeShape)inputTypeShape);
            shape.Draw();

            /* End Factory Shape */

            #endregion
        }

我正在做的事情是好的做法嗎? 還有另一種不為不同類型創建抽象工廠的方法嗎?

首先,始終問問自己該模式對您有何幫助,以及收益是否超過增加的復雜性。 不要僅僅因為閱讀過它們就使用模式。 對於像這樣的玩具示例,代碼可能會被壓縮為一個 switch 語句:

var shape = (shapeType, isRounded) switch
{
    (1, false) => new Square(),
    (1, true) => new RoundedSquare(),
    (2, false) => new Rectangle(),
    (2, true) => new RoundedRectangle(),
};

這涉及更少的代碼,因此往往更容易閱讀。

工廠和抽象工廠提供額外的抽象層。 這有時是需要的,比如如果你有大量的形狀,或者想減少組件的依賴性。 但是您通常應該小心您的抽象層,因為它們可能會“泄漏”。 考慮例如,如果你想創建一個圓或一條線,圓角線是什么? 還是非圓圈? 有關過度抽象的故意示例,請參閱fizzbuzz 企業版

您可能還想閱讀依賴注入 (DI)、控制反轉 (IoC) 和相關 IoC 庫的概念。 這可以幫助解決依賴鏈,即類將依賴作為構造函數參數。 在啟動時,您注冊應該在容器中使用的依賴項並從容器中請求一些特定類型的 object,然后容器將弄清楚如何創建所有依賴項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM