[toc]
简单工厂#
Q: 讲一下简单工厂模式#
A:
简单工厂模式不是23种设计模式里的一种,简而言之,就是有一个专门生产某个产品的类。
比如下图中的鼠标工厂,专业生产鼠标,给参数0,生产戴尔鼠标,给参数1,生产惠普鼠标。
注意这个参数, 我必须根据入参去确定返回
factory.create(int type)
Q: 简单工厂模式的缺点是什么?#
A:
当我试图新增一种类型, 我就得在create里新增case-when, 外面也要做类型的适配
但是由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
工厂方法模式#
Q: 讲一下工厂方法模式是什么?#
A: 把创建对象的操作集中到工厂方法中,工厂支持继承。
外界不关注内部怎么生成或者生成什么, 只要给了对应的工厂,返回给我正确的产品基类即可。
举例:
有1个父类模式
工厂接口A , 和 产品接口B
从接口上可以看出, 接口A.create()函数生产出产品B,
然后后面类似工厂->生产->产品的情况, 都继承过来
工厂类C继承接口A, 产品类D继承接口B。
于是工厂就有好多个了
当我试图切换产品,只需要切换工厂即可,不再需要给出方法入参了!
**
Q: 和简单工厂相比,优点是什么?#
A:
- 一个调用者想创建一个对象,只要知道其名称就可以了。
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
- 屏蔽产品的具体实现,调用者只关心产品的接口。(调用者不用想着我传啥参数了,是1还是2还是什么枚举,直接拿到这个工厂create就完事)
Q: 工厂方法的缺点是什么?#
A:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
注意: 这里的工厂方法,一般只有一个create()方法,没有其他的了, 所以模式名特地指出了”方法“二字
抽象工厂模式#
Q: 抽象工厂是什么?#
A:
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于 抽象工厂方法里的create有好几个,是一个产品族
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 换数据库只需换方言和驱动就可以