原文地址:创建型设计模式对比总结 设计模式(八)
创建型模式是new 的一种替代方式,可以将对象的创建与具体的类型进行分离
目前已经介绍了5种创建型设计模式(如果简单工厂算一种的话,那就是6种)
分别是:
简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式
简单工厂模式
静态工厂方法是一种最简单的创建的替代方法
基本上不涉及复杂的处理过程,可能执行的仅仅是包装、转换等
比如,一个静态方法,根据参数进行if else判断,或者switch选择进而确定需要创建的对象类型
比如,Long内部的valueOf 接受不同类型的参数,进而转换为Long类型对象
他可以是一个方法,也可以有多个静态方法
尽管通常简单工厂模式将只会创建一种类型的产品对象
但是,你也可以N个静态方法,创建N多种不同类型的对象
不过一般不这么用,不够清晰,没有条理杂乱,完全不符合单一职责原则
所以对于简单工厂模式,我们一般说简单工厂模式只能创建一种类型的产品
简单工厂模式它的核心就是:
一个类 静态方法 来解决对象的创建问题
一个类吃遍天下
工厂方法模式
简单工厂模式一个类吃遍天下,职责过多,就会有各种原因可能要修改这个类,好比你是两个班级的班主任,不管哪个班级的学生有事情都要找你。
既不符合单一职责原则,也不符合开闭原则
所以为了解决这个问题,进化出来工厂方法模式
工厂方法模式不再是一个类吃遍天下
工厂方法模式通过与产品等级结构相同的工厂等级结构,对产品进行创建
每个工厂不再是多个职责,仅仅创建一种类型的产品,符合单一职责
而且,对于新增的产品等级,只需要扩展工厂,而不需要修改现有的工厂
所以说工厂方法模式是简单工厂模式的标准版本,规范版本
工厂方法定义了一个用于创建对象的接口,他的子类(具体的工厂类)负责具体产品的创建
这个抽象的工厂角色并不知道他所创建的对象的具体类型,因为是子类决定了具体类型
将创建对象的职责委托给了多个子类中的一个,所以也说工厂方法模式将对象的创建延迟到其子类
比如
Creator creator = new ConcreteCreator();
Product product= creator.create();
客户端通过creator.create()获得产品
不用关心Creator具体的类型,也不知道Product具体的类型,都是面向抽象的编程
创建的产品的具体的类型完全是动态的根据creator的具体的类型ConcreteCreator决定的
所以工厂方法模式也叫做多态工厂模式
抽象工厂模式
工厂方法模式虽然解决了简单工厂模式中的各种问题,进行了升级改良
但是
工厂模式只能创建一种类型的产品
因为工厂模式的顶级抽象角色规定了创建的协议
他只有一种返回类型
为了解决工厂方法只能创建一种类型的产品的弊端,又拓展出抽象工厂的模式
将工厂的创建能力拓展到产品族
也就是顶级的抽象角色中,可以创建一系列类型的产品
这一系列类型的产品中的一员(每种类型一个)就组成了一个产品族的概念
实际使用的时候,一定要注意,他们必须要有产品族的概念
如果你没有产品族的概念,非要生搬硬套的组织在一起,比如一个工厂生产轮胎和CPU和热水袋,他们之间使用时毫无关联,必然不会符合单一职责原则
有了产品族的概念,而且这一族产品也很可能一起出现使用,才是抽象工厂模式最好的运用
当一个系统要由多个产品系列中的一个来配置时,典型的就是类似厂家替换这种场景,非常适合抽象工厂
建造者模式
在有了能够生产一族产品的能力之后,比如可以生产 轮胎 发动机
那么,就会有应用这一族产品的需求
对于这一族产品的运用,又可以将他们使用逻辑,也就是装配逻辑进行分离,这个分离就是建造者模式
建造者模式仅仅关心构造一个完整复杂产品的步骤,而不关心生产细节
细节由具体的builder进行实现
builder就相当于抽象工厂模式中的Creator,只不过builder还要负责每一个步骤的装配
建造者模式也通常借助于抽象工厂模式来进行实现,就是Creator也负责最终产品的组装交付
原型模式
原型模式类似与工厂模式
工厂模式是通过“创建” 来获得对象
而原型模式则是通过“复制”来获得对象
Java语言的机制---所有的类都继承自Object,使得Java天然的支持原型模式
只需要实现Cloneable接口即可,另外按照你的需要看是否实现clone方法
而对于稍微复杂点的原型模式下
比如创建的原型对象数量不固定或者产品种类较多,不方便管理,还出现了 带“管家”的原型模式
通过管理器这个管家对原型对象进行管理
他提供获取对象的方法
原型模式是另一种视角的创建
单例模式
单例模式逻辑含义比较简单,就是有些场景就是需要唯一的对象,或者说有些场景没必要使用多个对象。
保证类只有一个实例,并提供一个访问他的全局访问点
比如,原型模式中的管理器,除非特殊必要,否则他就应该是一个单例
再比如,windows的任务管理器
重点是实现的过程---如何保证的确只有一个对象被产生
这个全局唯一的访问点往往又是简单工厂模式---一个静态方法提供
对比、联系、区别
本身作为创建型模式,他们必然拥有相同的特征--“创建”对象,只不过是侧重点不同
而且各种类型模式之间,很难不发生点关系
最基本的共性就是都是用来创建对象,都是new的替代方法
简单工厂、工厂方法、抽象工厂、建造者、原型都是创建对象
而单例除了第一次创建,其余时候都是返回一个已经存在的对象
建造者模式又特别关注比较复杂的对象
简单工厂模式、工厂方法模式、抽象工厂模式都是工厂模式的形态之一
工厂方法模式是简单工厂模式的规范化与标准化扩展
如果只有一个具体工厂类,工厂方法模式自然可以改造成简单工厂模式
抽象工厂模式是工厂模式中最为抽象和最具一般性的一种形态
抽象工厂经常通过工厂方法来实现
(也可以借助于原型模式来实现,抽象工厂可以存储一个被拷贝的原型对象的集合,然后返回产品的对象)
简单工厂模式和工厂方法模式都是针对一个产品等级结构,而抽象工厂则可以生产多个等级结构的产品
建造者模式与抽象工厂模式都可以用来创建同时属于几个产品族的对象,也就是他们都可以创建复杂的对象
但是建造者模式进一步的对组装过程进行了分离
抽象工厂模式中,每一次的工厂对象调用都会创建一个完整的产品对象
客户端来决定到底如何处理这些产品,可以组装为更大的产品,也可能不会
建造者模式则关注借助于产品族的各个产品,一点点的构造出一个更为复杂的产品
而且,产品的组装过程发生在建造者内部封装起来
建造者模式重点在于组装,复杂对象构建逻辑的分离
但是复杂对象的的每一个组成部分往往又都是工厂模式创建
创建者模式与工厂模式经常结合使用
建造者模式在最后一步返回一个完整的产品(一般都是复杂的)
抽象工厂模式则是立即返回每一个产品,具体的产品如何处理随便你
所以说,建造者模式是抽象工厂模式在某种场景下的一种延伸拓展
单例模式保证只有一个对象,它提供了一个静态方法用于获取这个唯一的对象
所以说,单例模式使用了简单工厂模式
不过提供工厂方法的这个类就是他自身,而且静态方法返回的对象也是他自身,是自己的工厂
单例模式与其他创建型模式并不冲突也不矛盾
其他模式中的对象,也可以是单例的
创建型模式之间是相互发展,相互借鉴的,结合具体的情况,适用于不同的场合
工厂方法模式,抽象工厂模式是最基础的创建,以代替new 达到对象的创建与使用的隔离
建造者模式把产品组装为复杂的产品
原型模式是要求通过“复制”来创建,单例模式要求只能创建一个,是进一步的需求升级