.Net 设计模式进阶之路——抽线工厂模式[Abstract Factory]

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

  • ?欢迎点赞 :? 收藏 ⭐留言 ? 如有错误敬请指正,赐人玫瑰,手留余香!
  • ?本文作者:由webmote 原创,首发于 【掘金】
  • ?作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!???

? 01.抽象工厂模式

意图: 把生产一系列关联产品部件的工厂进行更抽象,比如把生产不同枪支部件的厂抽象为枪支抽象工厂,而具体的实体工厂可能是手枪,也可能是步枪等等。

问题领域: 它一般用来解决下列问题。

  • 产品和系统独立,
  • 产品包含一系列的部件需要构建,
  • 产品本身还有不同的类型
  • 产品仅提供接口,而非具体的类

解决方案: 我们使用UML图来描述它。

image.png
图中可以看出,每个抽线工厂的子类,均负责不同部分产品的生成,合并在一起构成了对整体产品的构造。

当然如果采用了生成器设计模式,那我们一般按照 XXXAbstractFactory来定义接口或实现类,这样其他童鞋看到这些类时,可以很快的Get到XXX点。

效果:

  • 好处:
  1. 抽象工厂封装了具体的类,其一般对外供调用的接口返回抽象产品类,这样对客户端隐藏了实现的细节;
  2. 可以方便的替换产品生成的工厂,以便产生另外的系列部件;
  3. 可以方便的控制产品各个部件生成的一致性。
  • 限定:
  1. 难以支持扩展产品的部件;因为扩展产品部件,意味着所有的实现类均需要修改,工作量繁重。

? 02. dotnet core 源码赏析

EF Core源代码内有一个表达式构建的工厂ISqlExpressionFactory构建时采用了抽象工厂模式。

public interface ISqlExpressionFactory
{
SqlBinaryExpression IsNotNull(SqlExpression operand);

    SqlUnaryExpression Convert(
        SqlExpression operand,
        Type type,
        CoreTypeMapping? typeMapping = null);

    SqlUnaryExpression Not(SqlExpression operand);

    SqlUnaryExpression Negate(SqlExpression operand);

    SqlFunctionExpression Function(
        string functionName,
        IEnumerable<SqlExpression> arguments,
        Type returnType,
        CoreTypeMapping? typeMapping = null);

}
复制代码

其生成器接口了不同的表达式构建接口,有SqlUnaryExpression表达式的构建,有SqlFunctionExpression表达式的构建,还有更多的其他类型的表达式构建,这里不一一列举了。

大家有兴趣的可以参看源代码:github.

通过这个抽象工厂,我们可以构建不同的表达式,最后生成出整体的sql表达式预制件。

有时候比较混淆简单工厂模式,工厂方法模式,还是抽象工厂模式,因为他们都属于工厂模式,在形式上也是极为相似的。

记住他们的最终目的都是为了解耦。

所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了,需求可扩展性是否达到了即可。

? 03. dotnet 抽象工厂实现

这是一个例子,我们来实现一个抽象工厂,接口定义如下:

abstract class AbstractFactory
    {
        public abstract AbstractProductA CreateProductA();
        public abstract AbstractProductB CreateProductB();
    }  
    class ConcreteFactory1 : AbstractFactory
    {
        public override AbstractProductA CreateProductA()
        {
            return new ProductA1();
        }
        public override AbstractProductB CreateProductB()
        {
            return new ProductB1();
        }
    }   
    class ConcreteFactory2 : AbstractFactory
    {
        public override AbstractProductA CreateProductA()
        {
            return new ProductA2();
        }
        public override AbstractProductB CreateProductB()
        {
            return new ProductB2();
        }
    }
复制代码

实现比较简单,在这里不列出了,等后续一块放在github上。

调用方,可以按照下列方式直接使用。

AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
client1.Run();

AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
client2.Run();

复制代码

是的,相对来说,抽线工厂是为了让创建工厂和一组产品与使用相分离,并可以随时切换到另一个工厂以及另一组产品,因此涉及到的类相对比较多,而我们的应用场景应该不会太多。

大部分产品的构建,使用简单工程或工厂方法即可完成。

? 04. 小结

是的,写文章好累,输出和输入是不一样啊,有这事件,可以刷好多抖音了,哈!

养成一个好习惯,需要不停的激励和鼓励,写作的能力也许就是不断的写中提升的,当然还有自身的额能力,在不断的输出过程中,发现自己的不足以及巩固自己的知识。

30天不停更,目标很远大,今天是第四天,加油吧,兄弟们!

例行小结,理性看待!

结的是啥啊,结的是我想你点赞而不可得的寂寞。???

?都看到这了,还在乎点个赞吗?

?都点赞了,还在乎一个收藏吗?

?都收藏了,还在乎一个评论吗?

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享