一文轻松理解工厂,抽象工厂,建造者

简介:用画图的方式理解工厂,抽象工厂,建造者。也讨论一下,到底应该在何时去使用这些模式。

工厂

在这里插入图片描述
上图的Factory和A,可以理解成接口或抽象类。

假设A有很多个实现类,A1,A2,A3。那么我们就要创建3个与之对应的工厂 —— F1,F2,F3。用来分别生产对应的A,如F1生产A1,F2生产A2。用图表示如下:
在这里插入图片描述
现在来看一下扩展性。由该图可知,当我们想要的接口A,有了新的实现类,如A4。那么只需让A4实现A接口,再新建Factory4去实现Factory接口并提供创建A4对象的方法,即可。而我们原来的代码,是不需要做任何修改的。
假设有10个用户,也用工厂得到到了A实例。那么当创建A的过程需要发生变化,只需要修改工厂的方法,所有的用户依然使用A a = f.createA();来获得对象,不需要做其它的改变。

同样,工厂模式还是有不足的。比如用户现在不仅仅需要A,还要A,B,C,D等,且ABCD拥有很强的关联性。
所谓的强关联性,举一个列子,现在有【手机,手机壳】两个对象,手机有 [苹果7][三星S10],手机壳有 [苹果7的壳][三星S10的壳],那么我们如果选[苹果7]和[三星S10的壳],是没有用的,那么手机和手机壳,就具有强关联性。
因为ABCD有强关联性,我们就想要让一个工厂,来生产这所有的东西,而不像之前只生产A一种。这就是抽象工厂模式。

抽象工厂

抽象工厂,在原来的基础上做了这样的升级:原先每个工厂只生产一个产品——A,现在每个工厂要生产一系列的产品——A,B,C,D。如图所示:
在这里插入图片描述
所以,抽象工厂模式里的工厂,相比于之前的工厂模式,最核心的区别就是工厂所生产的东西由一个变为了多个。

我们依然来看一下扩展性。首先如果有新的工厂要加入,那么工厂只需要实现Factory接口,并提供创建所有产品(ABCD等)对象的方法,即可。所以,原本的代码也是无需任何改变的。对于用户方面,如果有多个用户使用工厂接口来获得对象,当创建对象的方式发生变化时,依然只有工厂需要做出改变。
由此可见,工厂的这2个优点,在抽象工厂种是依然存在的。不过如果需要增加产品,那么所有的工厂都需要增加方法的实现类。并且,当工厂们所生产的产品并不是相同时,如厂1生产AB,厂2生产CD,由于都实现了Factory接口,就导致了工厂的实现类中,会提供"无意义的"方法,如厂1依然需要重写生产C和D的方法,即使返回的常常是null。

建造者

工厂的核心点在于把对象创建的控制权交给别人(工厂类或工厂方法),从而使得创建对象和使用对象相分离(解耦,创建对象的步骤发生变化时,不会直接影响到使用),并且保证了接口实现类增加时,程序整体是符合开闭原则的。
而建造者模式的关注点在于,虽然工厂把对象的创建交给了别人,但是创建的过程也许十分复杂和繁琐,那么就要依靠该模式,来使得这一繁琐过程被上层屏蔽,使我们只需要关心获得的对象,而无需关心如何获得。
具体的例子可以参考:建造者模式举例。

建造者的思想是:客户依赖指挥者,指挥者负责合理使用建造者的建造函数,建造者的建造函数用来构建不同参数的对象。可以看出,虽然建造的方式复杂,但造出来的,依然是一个特定数据类型的对象,并没有涉及到多种类型的产品,而是一种产品的多种参数形态。下面我们来看一下抽象工厂和建造者模式的对比:

对比

本文举例的设计模式,都属于创建型模式。
工厂,主要强调的是,在获取多种具有相同接口的数据类型时,应该如果设计程序。它体现了程序对接口的依赖,而不是依赖于具体的实现类。让我们在获得同一接口的不同产品时,可以有统一的获得方式。
抽象工厂,某几个对象具有“强相关性”,并且这些对象都有很多的具体实现类,那么就可以使用抽象工厂。
建造者,获得的对象内部依赖了其它的对象,并且这些对象创建的过程繁琐,对象之间创建的顺序也复杂,那么就可以使用该模式。
所以,用工厂系列还是建造者的关键点就在于,我们要获得的是一类对象还是一个对象,一类的话选工厂的话,如果创建的过程复杂,选建造者。如果是一类对象,并且实现类的创建也复杂,那么就可以二者结合使用。


如:我想要电脑,手机,平板,音响,耳机生态五件套。这里的电脑,手机等,就明显应该是接口,而不是具体的某类手机。因为强调了生态,所以可以选苹果五件套或小米五件套。那么就可以依赖一个“五件套”工厂,其实现类有苹果工厂,小米工厂等。再来看苹果工厂,造一个苹果电脑的过程,明显是复杂的,那么就可以使用建造者模式,让一个指挥者,来决定先装屏幕还是先装键盘,再让指挥者去喊建造者,让不同建造者去造不同的屏幕(或贵或便宜,但都是同一个数据类型——屏幕)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值