设计模式三-----抽象工厂模式

mac2022-10-04  28

设计模式三-----抽象工厂模式

​ 抽象工厂模式与之前介绍的简单工厂模式和工厂方法模式目的一样,由于目标可能经常变化,因此需要通过工厂把这个创建的过程封装起来,让客户不需要自己直接new()目标类型。

​ 简单工厂职责:构造某个具体类型,然后把实例作为抽象类型返回; ​ 工厂方法职责:进一步抽象出一个抽象的创建者和一个抽象的产品类型,而实际的执行过程是具体工厂创建具体的产品类型;

​ 项目中,有时要创建的不是继承“一个”抽象类型的产品,他们本身就是多个具有一定依赖关系,但非同源的类型,因此,需要提供另一种形式的工厂,它可以产生“一系列”具有相关依赖关系的类型。

一、抽象工厂适用场景

​ 如果客户程序希望将业务逻辑和产品创建相分离,把一系列产品的创建,甚至一系列中某些产品的组合全部放在抽象工厂内部解决。

​ 当然,也可以让抽象工厂“大材小用”,让他的实际效用退化为工厂方法模式。

二、抽象工厂模式缺点

​ 在经典抽象工厂模式中,增加新的产品类别时就要对工厂接口进行“伤筋动骨”的修改。

​ 可以通过泛型、委托、反射和相关配置来弥补经典抽象工厂的不足。

解决方法: ​ 本着开闭原则(OCP),我们希望通过继承获得支持IProductC的新抽象工厂。这样从保持客户程序稳定的角度看,我们可以调整抽象工厂的创建方式,确保抽象工厂自身扩展时,抽象工厂的构造过程也可以与客户程序分离,如下图所示:

​ 客户程序获得抽象工厂AbstractFactory接口和扩展的抽象工厂接口(ExtendAbstractFactory)并不是自己直接new ConcreateFactory X()实现的,这个过程也是借助工厂方法模式完成那个IFactory实现的,客户程序与具体抽象工厂类型的直接依赖关系被Factory隔断了。

​ 从定位看,IFactory负责纯技术层面各类产品的构造工作,而各个抽象工厂接口设计更为贴近面向某个业务领域的需求。

​ 通过这个设计,工厂方法模式和抽象工厂模式的实现过程更加灵活,客户程序也将产品类型及工厂类型自身的变化隔离在“视野”外,真正实现两个创建型模式的初衷,而不是始终或多或少地在客户程序、具体工厂类型、具体产品类型之间保持着“藕断丝连”的依赖关系。

三、基于委托的生产外包

​ 我们要留意对象创建的时机

​ 本质上客户程序访问某个抽象的工程类型,获得抽象的产品,都是异步响应的。因此Factory需要能提供异步通知的能力。

​ 举个例子,在现实中,客户下单之后,不是客户盯着工厂生产了多少产品、数产品数量,而是工厂完成任务后告诉客户“OK”。如果工厂还兼做二级代理的批发,那么在他加工一批产品后还会通知多个代理商来提货。这时,等待加工产品的客户程序和工厂类型之间形成了生产上的“委托-代理”关系。 ​ 即,客户程序需要某个产品的时候委托工厂类型来完成,工厂类型接受委托后,选择需要new的具体产品类型,调用具体产品类型的构造过程,这时过程类型又相当于是监督具体产品的构造过程的监理(代理人),待具体产品类型实例化后,工厂再按照先前谈定的委托要求,把加工好的实例反馈给客户程序。

​ 基于委托的异步抽象工厂如下图所示,

其中 ​ 1.客户程序调用工厂的工厂方法,同时把加工后怎么通知它的委托也传递给工厂 ​ 2.工厂收到客户程序请求后,反馈“知道了”,但此时IProduct其实没有构造完成 ​ 3.工厂完成产品的创建工作 ​ 4.待生产IProduct后,按照之前客户告诉他的委托,通知回去,完成整个加工步骤 Tips: ​ 对于没有委托或函数指针的编程语言而言,可以通过一个具有回调方法的接口完成。

​ 异步调用工厂关键思想就是给构造过程中增加第二个、第三个“预先安排好”的出口。如果说控制反转做的是“Don‘t call me,I’ll call you”,那么这里的异步工厂做的就是"OK,I’ll call you,but later"。

四、小结

​ 抽象工厂模式是简单工厂的升华,它除了解决对象构造过程后之外,更主要的是提供了一组“相关或具有依赖关系”类型的构造过程,也就是具有了对一组类型构造过程组合和调度的能力;相对工厂方法而言,它更像一个“封装”的工厂,而不是简单地提供创建某个类型产品的”方法“。

​ 使用时可以把工厂方法、静态工厂、简单工厂和抽象工厂混合使用,建议布局:

1 静态工厂可以作为最底层的一个“泵”,它提供最原始但粗细粒度对象的创建,甚至仅仅返回最弱类型的object也可以,后绑定调用(或被称为晚绑定)可以通过一个集中的静态工厂完成。 ​ 之所以把它放在最下面,主要是他不能进一步被继承和扩展,所以让他做基本但又最通用的工作。实际项目中可以用Activator类充当这个角色。 2 简单工厂的适用范围很广,根据应用的需求在某些需要隔绝抽象与具体的位置上使用。 3 工厂方法应用在具有一套较纵深层次的对象上,可以通过具体抽象工厂类型选择继承层次上一个合适的具体产品来构造,而客户程序则把握抽象工厂的工厂类型和抽象产品类型即可。 4 抽象工厂方法则用在某些特定的领域上,面向某些应用子系统或专业领域对象的创建工作,相对而言,我们可以把它更多地应用于项目的中、高层设计中。

最新回复(0)