这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
- ?欢迎点赞 :? 收藏 ⭐留言 ? 如有错误敬请指正,赐人玫瑰,手留余香!
- ?本文作者:由webmote 原创,首发于 【掘金】
- ?作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!???
? 01.抽象工厂模式
意图: 把生产一系列关联产品部件的工厂进行更抽象,比如把生产不同枪支部件的厂抽象为枪支抽象工厂,而具体的实体工厂可能是手枪,也可能是步枪等等。
问题领域: 它一般用来解决下列问题。
- 产品和系统独立,
- 产品包含一系列的部件需要构建,
- 产品本身还有不同的类型
- 产品仅提供接口,而非具体的类
解决方案: 我们使用UML图来描述它。
图中可以看出,每个抽线工厂的子类,均负责不同部分产品的生成,合并在一起构成了对整体产品的构造。
当然如果采用了生成器设计模式,那我们一般按照 XXXAbstractFactory
来定义接口或实现类,这样其他童鞋看到这些类时,可以很快的Get到XXX点。
效果:
- 好处:
- 抽象工厂封装了具体的类,其一般对外供调用的接口返回抽象产品类,这样对客户端隐藏了实现的细节;
- 可以方便的替换产品生成的工厂,以便产生另外的系列部件;
- 可以方便的控制产品各个部件生成的一致性。
- 限定:
- 难以支持扩展产品的部件;因为扩展产品部件,意味着所有的实现类均需要修改,工作量繁重。
? 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天不停更,目标很远大,今天是第四天,加油吧,兄弟们!
例行小结,理性看待!
结的是啥啊,结的是我想你点赞而不可得的寂寞。???
?都看到这了,还在乎点个赞吗?
?都点赞了,还在乎一个收藏吗?
?都收藏了,还在乎一个评论吗?