工厂方法模式
定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
四要素
- 工厂接口
工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。在实际编程中,有时候也会使用一个抽象类来作为与调用者交互的接口,其本质上是一样的。 - 工厂实现
在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。 - 产品接口
产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。 - 产品实现
实现产品接口的具体类,决定了产品在客户端中的具体行为。
抽象工厂模式
定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
产品族
位于不同产品等级结构中,功能相关联的产品组成的家族。
四个角色
- 抽象工厂角色
这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 - 具体工厂角色
它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。 - 抽象产品角色
它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。 - 具体产品角色
具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
跟工厂方法模式的区别
和工厂方法模式的区别就在于需要创建对象的复杂程度上。
单例模式
定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
实现
让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。
多线程时的单例
class Singleton {
private static Singleton instance;
private static final String LOCK = "lock";
private Singleton() {
}
private static Singleton getInstance() {
//双重锁定
//实例未被创建的时候再加锁处理
if(null == instance) {
synchronized(LOCK) {
if(null == instance) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 懒汉式单例类
在第一次被引用时,才会将自己实例化。(如上) - 饿汉单例类
静态初始化的方法是在自己被加载时就将自己实例化。
//关键字final使得该类不能被继承
class final Singleton {
//在第一次引用类的任何成员时创建实例
//公共语言运行库负责处理变量初始化
private static final Singleton instance = new Singleton();
private Singleton() {
}
private static Singleton getInstance() {
return instance;
}
}
- 两者区别
饿汉式,是类一加载就实例化对象,所以要提前占用系统资源;而懒汉式,又会面临着多线程访问的安全性问题,需要做双重锁定这样的处理才能保证安全。 - 如何选择
根据实际的需求选择使用哪一种方式。一般饿汉式的单例类已经足够满足我们的需求了。
建造者模式
定义
将一个负责对象的构造与它的表示分离,使得同样的构建过程可以创建不同的表示。
三要素
- Builder
是为创建一个Product对象的各个部件指定的抽象接口。 - ConcreteBuilder
具体建造者,实现Builder接口,构造和装配各个部件。 - Director
指挥者,构建一个使用Builder接口的对象。 - Product
各个部件组成的具体产品。
模式适用情况
用于创建一些复杂的对象,这些对象内部创建间的顺序通常是稳定的,但是对象内部的构建通常面临复杂的变化。
好处
使得构造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
原型模式
- 定义
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 - 实现
Java中Object的clone()方法 - 注意深拷贝与浅拷贝的区别