设计模式中的简单工厂、工厂模式、抽象工厂模式总是分不清?一文告诉你所有区别

举报
breakDawn 发表于 2022/03/24 00:55:34 2022/03/24
【摘要】 简单工厂Q: 简单工厂模式是什么?A:简单工厂模式不是23种设计模式里的一种,简而言之,就是有一个专门生产某个产品的类。比如下图中的鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标。注意这个参数, 我必须根据入参去确定返回factory.create(int type)Q: 简单工厂模式的缺点是什么?A:当我试图新增一种类型, 我就得在create里新增case-w...

简单工厂

Q: 简单工厂模式是什么?
A:
简单工厂模式不是23种设计模式里的一种,简而言之,就是有一个专门生产某个产品的类。
比如下图中的鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标。
注意这个参数, 我必须根据入参去确定返回
factory.create(int type)
image.png

Q: 简单工厂模式的缺点是什么?
A:
当我试图新增一种类型, 我就得在create里新增case-when, 外面也要做类型的适配

但是由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;


工厂方法模式

Q: 工厂方法模式是什么?
A: 把创建对象的操作集中到工厂方法中,工厂支持继承。
外界不关注内部怎么生成或者生成什么, 只要给了对应的工厂,返回给我正确的产品基类即可。
举例:
有1个父类模式
工厂接口A , 和 产品接口B
从接口上可以看出, 接口A.create()函数生产出产品B,

然后后面类似工厂->生产->产品的情况, 都继承过来

工厂类C继承接口A, 产品类D继承接口B。
于是工厂就有好多个了

当我试图切换产品,只需要切换工厂即可,不再需要给出方法入参了!
image.png

**
Q: 和简单工厂相比,优点是什么?
A:

  • 一个调用者想创建一个对象,只要知道其名称就可以了。
  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。(调用者不用想着我传啥参数了,是1还是2还是什么枚举,直接拿到这个工厂create就完事)

Q: 工厂方法的缺点是什么?
A:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

注意: 这里的工厂方法,一般只有一个create()方法,没有其他的了, 所以模式名特地指出了”方法“二字


抽象工厂模式

Q: 抽象工厂是什么?
A:
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于 抽象工厂方法里的create有好几个,是一个产品族
image.png


Q: 抽象工厂相比工厂方法模式的改进?
A:
工厂方法模式只有1种create, 当你要新增一类产品的时候, 得重新设计工厂接口类。
而抽象工厂中, 直接工厂接口类上新增方法, 后面的子类同一实现即可。
新增接口方法, 不需要再新增接口类

  • 因此这个工厂更像一个有很多能力的大工厂了, 不再是一个简单的create()了

抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。


Q: 抽象工厂的缺点?
A:
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。


Q: 那工厂方法模式和抽象工厂模式的应用在哪呢??
A:

  • 我们最常用的 Spring 就是一个最大的 Bean 工厂,IOC 通过FactoryBean对Bean 进行管理。
  • 我们使用的日志门面框架slf4j,点进去就可以看到熟悉的味道 private final static Logger logger = LoggerFactory.getLogger(HelloWord.class);
    而这里的工厂实现,通过类加载去获取,应用开发者根本不需要关心背后实现是什么。 项目维护人员维护好日志jar包和配置即可。
  • JDK 的 Calendar 使用了简单工厂模式Calendar calendar = Calendar.getInstance();
  • 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
  • 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。
  • 比如 Hibernate 换数据库只需换方言和驱动就可以
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。