- 特点
- 对类的实例化过程的抽象。一些系统在创建对象时,需要动态地决定怎样创建对象,创建哪些对象,以及如何组合和表示这些对象。创建模式描述了怎样构造和封装这些动态的决定。包含类的创建模式和对象的创建模式。
- 都是为了创建对象,工厂模式用工厂类提供的方法创建,builder模式通过builder类提供的方法创建,原型模式通过clone方法创建
- 种类
-
单例模式(Singleton)
- 对调用者只暴露GetInstance()方法
- 多种实现
-
单锁懒汉方式
- 解决线程内安全问题?解决多线程问题,但是在性能上降低的
-
双重锁懒汉方式
- 和单锁方式优缺点类似,但线程不是每次都加锁(单线程不用加lock,性能提升了);并且允许实例化延迟到第一次访问对象时发生(只有第一次才创建)
- 还要注意new的过程中出现问题,其并不是一个原子操作
public class LasySingletonMode { public static void main(String[] args) { LasySingleton instnace = LasySingleton.getInstnace(); } } class LasySingleton { /** * 私有化构造方法,禁止外部直接new对象 */ private LasySingleton() { } /** * 给予一个对象作为返回值使用 */ private static volatile LasySingleton instnace; /** * 给予一个获取对象的入口 * * @return LasySingleton对象 */ public static LasySingleton getInstnace() { if (null == instnace) { synchronized (LasySingleton.class) { if (null == instnace) { instnace = new LasySingleton(); } } } return instnace; } }
-
饿汉方式
- 声明静态变量Instance时就初始化
- 推荐使用在.NET框架中,因为依赖.Net Framwork内部进行处理变量的初始化
- **Java中也有类似的机制,内部枚举的方式由jvm来保证new EnumSingleton只被实例化一次 **
public class EnumSingLeton { private EnumSingLeton(){ } public static EnumSingLeton getInstance(){ return SingLeton.INSTANCE.getInstance(); } private enum SingLeton{ INSTANCE; private EnumSingLeton enumSingLeton; SingLeton(){ enumSingLeton=new EnumSingLeton(); } public EnumSingLeton getInstance(){ return enumSingLeton; } } public static void main(String[] args) { System.out.println(EnumSingLeton.getInstance()); } }
-
-
工厂模式
- 从上到下越来越抽象
- 主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。
- 对调用者只暴露工厂类,产品类(消费/使用产品时需要使用产品对象)
- 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
- 简单工厂(Simple Factory)
- 一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
- 不修改代码的话,是无法扩展的
*由单独一个工厂对象根据参数决定创建出 **一种产品类 **的实例
- 工厂方法(Factory Method)
- 针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
- 在同一等级结构中,支持增加任意产品。
- 由一种工厂类的实例决定创建出一种产品类的实例,工厂中的生产方法不再需要参数
- 又称多态性工厂模式,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
- 抽象工厂(Abstract Factory)
- 有了产品族的概念,即产品又多了一层分类和抽象
- 由一种工厂类的实例决定创建出一个产品族下的多种产品的实例,工厂中的生产方法不再需要参数
- 每个工厂类不再只能创建一个产品实例,而是有了多个方法,可以创建同一产品族中的不同产品
- 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
- 对比
- 优点
- 简单工厂优点:客户端可以免除直接创建产品对象的责任,而仅仅是“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。
- 工厂方法优点:允许系统在不修改现有具体工厂角色的情况下引进新产品,即可以在需要时只增加代码而不修改现有代码。
- 抽象工厂优点:向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象 。效果和工厂方法模式类似,但增加了对产品族的支持。这个要看实际应用场景
- 区别
- 简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
- 工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
- 抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
- 不同点
- 简单工厂方法中,包括一个“抽象产品类”(该类可以是接口Interface,也可以是实际的类Class),所有需要的产品类都是该“抽象产品类”的子类(如果是接口的话,那么就是说所有产品类都继承了该接口)。
- 抽象工厂中,包括“抽象工厂类”和“抽象产品类”,同时包含不只一个工厂类。所有的工厂类都必须是“抽象工厂类”的子类,所有的产品都必须是“抽象产品类”的子类。
- 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
- 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个
- 优点
-
建造者/创建者模式(Builder)
- 重点是一个或一类产品的构造就比较复杂,需要分步骤或者分组件,抽象父类中定义有哪些步骤及顺序,然后这个过程的每一步或每一部分都可以有不同的实现,实现中会创建组合的产品的某个部分。
- 对调用者来说直接使用Director指挥类,不关心构建细节,只需要告诉它要什么产品。当然,需要先在Director的构造函数中指定用哪一个Builder实现类(即组合的方式,并且构造函数定义时的参数是Builder的抽象类型)。
- 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式
- 适用场景
- 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
- 需要生成的产品对象的属性相互依赖,需要指定其特定的生成顺序。
- 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
- 常用于构造组成复杂的对象,往往由很多部分构成,比如http的header。
- 优点
- 客户端不需要知道具体创建对象的细节,将产品本身和产品的创建过程解耦,相同的创建过程可以创建出不同的产品对象。
- 每个具体建造者相对独立,增加新的具体建造者不会影响现有的类库代码,符合开闭原则。
- 可以采用钩子方法精确的控制某个具体建造者是否需要某个部件。可以针对的控制产品构建流程。
- 缺点
- 如果产品之间的差异性较大,那么即使使用钩子方法来控制,那也是极其麻烦,且公共接口很难抽象。非常不适合
-
原型模式(Prototype)
- 通常用来在具体实现类的clone()中实现深拷贝,避免使用默认的clone()实现
- 对调用者只暴露clone()方法
- clone()方法
- 浅拷贝、深拷贝
- 利用序列化、反序列化进行深拷贝
-