简单工厂
简单工厂其实不是gof中的一员,它只是将创建对象的逻辑封装起来而已,以最简单的方式解耦。
简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。
所有的产品有一个共同的抽象,这些产品依赖该抽象,上层模块也依赖该抽象,工厂负责创建具体产品,简单的封装就实现了上层模块与具体产品之间的解耦。
如果将创建产品的方法定义为static,便是传说中的静态工厂,使用时不需要去实例化工厂类,静态工厂方法常常被用来替代类的构造器,这样的好处有:
- 命名上更具有可读性:构造器只能从参数作区分,很混乱
- 新建对象时不需要每次在被调用的时候都构造一个新的对象,可以在方法内部实现任何我们想要的逻辑,比如缓存对象等。
- 可以返回该类型的子类对象!!!!!!!
- 简化参数化类型的对象创建:典型的如
public static <K, V> HashMap<K, V> newInstance() {
return new HashMap<K, V>();
}
Map<String, List<String>> m = HashMap.newInstance();
静态工厂方法的缺点:
- 构造函数被设置为private,只提供静态工厂方法来创建对象,那么我们就不能通过继承的方式来扩展该类(构造函数也可以不设置为private,或者使用组合的方式来扩展 也可以规避这个问题)
- 静态构造方法不能和其他的静态方法很方便的区分开来(用命名规则可以很好的解决这一点)
最后简单工厂自身的缺点:
1.违背了“系统对扩展开放,对修改关闭”的原则,新增加一个产品的时候必须修改工厂类
2.当产品有各种明显的维度类别划分的时候,一个简单工厂管理会太混乱。
工厂方法
工厂方法模式主要是针对产品自身需要有不同的类别划分时,分别以相应的工厂来创建对应类别的产品。<b>需要特别注意的是:图中的creator并不是一个工厂父类,它只是一个拥有一个抽象的工厂方法的普通类,只是它依赖一个产品实例而已,通常这个creator也是有类别或者职责划分的,每一种creator都有自己创建产品的逻辑,新的creator接入必须继承自creator并实现自己的创建逻辑,所以从这个层面来讲其实工厂方法模式也并不是按照产品分类划分,而是不同的creator自身决定需要以不同的方式来创建产品而已(有点绕,但是这才是真理!!所有本自然段第一句话我觉得自己写错了~~~)</b>,图中BuldCreator为什么负责创建BulbLight,并不是从Light这一层来思考他们是一类的,而是从creator的角度来思考它们是一类的!!!
so,标准的工厂方法模式应该是以继承来实现的,客户端类中有自己的业务逻辑,然后有一个抽象的方法,要添加新的产品就新写一个类继承自该抽象类即可。
工厂方法模式相比简单工厂,我觉得就是对creator来说有一些自己的DIY而已!
以上感想是通过10遍阅读理解headfirst设计模式第159页,抽象工厂与工厂方法对话中领悟总结出来的,网上对工厂方法模式的介绍大多数都是有偏差的!!
抽象工厂
经过了对工厂方法的思考,对于抽象工厂,其实本质是一模一样的,虽然实现上有差别。抽象工厂其实也是按照客户端的需要进行划分。
抽象工厂与工厂方法的差别:
1.抽象工厂一般是使用组合的形式实现,客户端持有工厂类的实例。
2.最主要的区别:抽象工厂可以创建一系列产品,它可以将一些列的产品创建集中起来。如果抽象工厂类只有一个方法(只创建一个产品),他也不会是工厂方法模式,工厂方法模式是使用继承~~~~。
抽象工厂的缺点:如果产品族里新增或删除了产品,必须修改工厂接口类,然后每个具体的工厂都需要同步修改,这一点也是没办法,抽象工厂本身就是用来创建产品族的~~~~~~
依赖倒置原则
工厂三兄弟很好的诠释了依赖倒置原则:
客户端都依赖于产品的抽象,各自产品也依赖于产品自身的抽象。关于依赖倒置和spring的依赖注入,ioc异同,后续会有单独分析的文章。
网友评论