美文网首页
设计模式之抽象工厂模式

设计模式之抽象工厂模式

作者: ljchengx | 来源:发表于2020-11-10 15:22 被阅读0次

设计模式之抽象工厂模式

一、定义

抽象工厂是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

二、方案

抽象工厂模式建议为系列中的每件产品明确声明接口 (例如椅子、 沙发或咖啡桌)。 然后, 确保所有产品变体都继承这些接口。 例如, 所有风格的椅子都实现 椅子接口; 所有风格的咖啡桌都实现 咖啡桌接口, 以此类推。客户端代码可以通过相应的抽象接口调用工厂和产品类。 你无需修改实际客户端代码, 就能更改传递给客户端的工厂类, 也能更改客户端代码接收的产品变体。

三、适合应用场景

  1. 如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
  2. 如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。

四、实现方式

  1. 以不同的产品类型与产品变体为维度绘制矩阵。
  2. 为所有产品声明抽象产品接口。 然后让所有具体产品类实现这些接口。
  3. 声明抽象工厂接口, 并且在接口中为所有抽象产品提供一组构建方法。
  4. 为每种产品变体实现一个具体工厂类。
  5. 在应用程序中开发初始化代码。 该代码根据应用程序配置或当前环境, 对特定具体工厂类进行初始化。 然后将该工厂对象传递给所有需要创建产品的类。
  6. 找出代码中所有对产品构造函数的直接调用, 将其替换为对工厂对象中相应构建方法的调用。

五、优缺点

  • 你可以确保同一工厂生成的产品相互匹配。✔
  • 你可以避免客户端和具体产品代码的耦合。✔
  • 单一职责原则。 你可以将产品生成代码抽取到同一位置, 使得代码易于维护。✔
  • 开闭原则。 向应用程序中引入新产品变体时, 你无需修改客户端代码。✔
  • 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。×

六、代码实例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignModel.FactoryMethod
{
    /// <summary>
    /// 抽象工厂接口声明一组方法,这些方法返回不同的抽象产品。这些产品被称为一个系列
    /// 与高层次的主题或概念相关的。一个家庭的产品是他们通常能够相互合作
    /// 一个系列的产品可以有几个变体,但其中一个变体的产品不兼容用别人的产品
    /// </summary>
    public interface IAbstractFactory
    {
        IAbstractProductA CreateProductA();

        IAbstractProductB CreateProductB();
    }


    class ConcreteFactory1 : IAbstractFactory
    {
        public IAbstractProductA CreateProductA()
        {
            return new ConcreteProductA1();
        }

        public IAbstractProductB CreateProductB()
        {
            return new ConcreteProductB1();
        }
    }

    class ConcreteFactory2 : IAbstractFactory
    {
        public IAbstractProductA CreateProductA()
        {
            return new ConcreteProductA2();
        }

        public IAbstractProductB CreateProductB()
        {
            return new ConcreteProductB2();
        }
    }


    /// <summary>
    /// 产品系列中的每个不同产品都应该有一个基本接口。
    /// 产品的所有变体都必须实现此接口。
    /// </summary>
    public interface IAbstractProductA
    {
        string UsefulFunctionA();
    }

    class ConcreteProductA1 : IAbstractProductA
    {
        public string UsefulFunctionA()
        {
            return "产品A1的结果";
        }
    }

    class ConcreteProductA2 : IAbstractProductA
    {
        public string UsefulFunctionA()
        {
            return "产品A2的结果";
        }
    }

    public interface IAbstractProductB
    {
        /// <summary>
        /// 产品B做自己的事情
        /// </summary>
        /// <returns></returns>
        string UsefulFunctionB();

        /// <summary>
        /// 但它也可以与产品合作。
        /// 抽象工厂确保它生产的所有产品都是有价值的
        /// 相同的变体,因此,兼容。
        /// </summary>
        /// <param name="collaborator"></param>
        /// <returns></returns>
        string AnotherUsefulFunctionB(IAbstractProductA collaborator);
    }

    class ConcreteProductB1 : IAbstractProductB
    {
        public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
        {
            var result = collaborator.UsefulFunctionA();
            return $"这是B1与{result}合作";
        }

        public string UsefulFunctionB()
        {
            return "产品B1的结果";
        }
    }

    class ConcreteProductB2 : IAbstractProductB
    {
        public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
        {
            var result = collaborator.UsefulFunctionA();
            return $"这是B2与{result}合作";
        }

        public string UsefulFunctionB()
        {
            return "产品B2的结果";
        }
    }
}


namespace DesignModel
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("用第一种工厂类型测试相同的客户端代码");
            ClientMethod(new ConcreteFactory1());
            Console.WriteLine();

            Console.WriteLine("用第二种工厂类型测试相同的客户端代码");
            ClientMethod(new ConcreteFactory2());


            Console.ReadLine();

        }

        public static void ClientMethod(IAbstractFactory factory)
        {
            var productA = factory.CreateProductA();
            var productB = factory.CreateProductB();

            Console.WriteLine(productB.UsefulFunctionB());
            Console.WriteLine(productB.AnotherUsefulFunctionB(productA));
        }
    }
}

B7qOL8.png

相关文章

网友评论

      本文标题:设计模式之抽象工厂模式

      本文链接:https://www.haomeiwen.com/subject/utjjbktx.html