1. 单例模式
-
定义
- 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
-
代码
/** * 单例模式-饿汉形式 * @author emma_zhang * @date 2019/2/15 */ public class SingletonForHunger { private static final SingletonForHunger SINGLETON_FOR_HUNGER = new SingletonForHunger(); private SingletonForHunger() { // 限制产生多个实例 } /** * 访问实例 */ public static SingletonForHunger getSingletonForHunger() { return SINGLETON_FOR_HUNGER; } public static void doSomething() { // 其他方法,尽量使用static } } /** * 单例模式-懒汉形式 * * @author emma_zhang * @date 2019/2/15 */ public class SingletonForLazy { private static SingletonForLazy singletonForLazy = null; private SingletonForLazy() { // 限制产生多个对象 } /** * 产生实例对象,必须要加同步,不然在多线程下可能出错 * * @return 实例对象 */ public synchronized static SingletonForLazy getSingletonForLazy() { if (singletonForLazy == null) { singletonForLazy = new SingletonForLazy(); } return singletonForLazy; } }
-
使用场景
- 要求生成唯一序列化的环境
- 在整个项目中需要一个共享访问或者共享数据点
- 创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源
- 需要定义大量的静态变量和静态方法(工具类)的环境
2. 工厂方法模式
-
定义
- 定义一个用于创建对象的接口,让子类决定实例化哪一个类
- 工厂方法使一个类的实例化延迟到其子类
-
通用源码
/** * 抽象产品类 * @author emma_zhang * @date 2019/2/18 */ public abstract class Product { /** * 产品的公共方法 */ public void method(){ } /** * 抽象方法 */ public abstract void method2(); } /** * 具体产品类 * * @author emma_zhang * @date 2019/2/18 */ public class ConcreteProduct1 extends Product { @Override public void method2() { } } /** * 抽象工厂类 * * @author emma_zhang * @date 2019/2/18 */ public abstract class Creator { /** * 输入参数可以自行匹配,通常为string,enum,class等 * * @param c * @param <T> * @return */ public abstract <T extends Product> T createProduct(Class<T> c); } /** * 具体工厂类 * * @author emma_zhang * @date 2019/2/18 */ public class ConcreteCreator extends Creator { @Override public <T extends Product> T createProduct(Class<T> c) { Product product = null; try { product = (Product)Class.forName(c.getName()).newInstance(); } catch (Exception e) { // 处理异常 e.printStackTrace(); } return (T)product; } } /** * 场景类 * * @author emma_zhang * @date 2019/2/18 */ public class Client { public static void main(String[] args) { Creator creator = new ConcreteCreator(); Product product = creator.createProduct(ConcreteProduct1.class); // 继续业务处理 } }
-
应用场景
- new一个对象的替代品
- 需要灵活的,可扩展的框架时,考虑使用工厂方法模式
-
扩展
- 简单工厂模式:将ConcreteCreator中改为静态【static】方法,同时去掉抽象类,简化了类的创建过程
- 升级为多个工厂方法:一个具体类对应一个工厂
3. 抽象工厂模式
-
定义
- 为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类
- 在场景类中,没有任何一个方法与实现类有关系,对于一个产品来说,我们只要知道它的工厂方法就可以直接产生一个产品对象,无须关系它的实现类
-
通用源码
/** * 抽象产品类 * * @author emma_zhang * @date 2019/2/19 */ public abstract class AbstractProductA { public void sharedMethod() { // 每个产品共有的方法 } /** * 共有的方法,但不同的实现 */ public abstract void doSomething(); } /** * 产品A1的实现类 * * @author emma_zhang * @date 2019/2/19 */ public class ProductA1 extends AbstractProductA { @Override public void doSomething() { System.out.println("产品A1的实现方法"); } } /** * 产品A2的实现类 * * @author emma_zhang * @date 2019/2/19 */ public class ProductA2 extends AbstractProductA { @Override public void doSomething() { System.out.println("产品A2的实现类"); } } /** * 抽象产品类 * * @author emma_zhang * @date 2019/2/19 */ public abstract class AbstractProductB { public void sharedMethod() { // 每个产品共有的方法 } /** * 共有的方法,但不同的实现 */ public abstract void doSomething(); } /** * 产品B1的实现类 * * @author emma_zhang * @date 2019/2/19 */ public class ProductB1 extends AbstractProductB { @Override public void doSomething() { System.out.println("产品B1的实现方法"); } } /** * 产品B2的实现类 * * @author emma_zhang * @date 2019/2/19 */ public class ProductB2 extends AbstractProductB { @Override public void doSomething() { System.out.println("产品B2的实现类"); } } /** * 抽象工厂 * * @author emma_zhang * @date 2019/2/19 */ public abstract class AbstractCreator { /** * 构建产品A * * @return 产品A */ public abstract AbstractProductA createProductA(); /** * 构建产品B * * @return 产品B */ public abstract AbstractProductB createProductB(); } /** * 产品等级1的实现 * * @author emma_zhan * @date 2019/2/19 */ public class Creator1 extends AbstractCreator { @Override public AbstractProductA createProductA() { return new ProductA1(); } @Override public AbstractProductB createProductB() { return new ProductB1(); } } /** * 产品等级2的实现 * * @author emma_zhang * @date 2019/2/19 */ public class Creator2 extends AbstractCreator { @Override public AbstractProductA createProductA() { return new ProductA2(); } @Override public AbstractProductB createProductB() { return new ProductB2(); } } /** * 场景类 * * @author emma_zhang * @date 2019/2/19 */ public class Client { public static void main(String[] args) { AbstractCreator creator1 = new Creator1(); AbstractCreator creator2 = new Creator2(); AbstractProductA a1 = creator1.createProductA(); AbstractProductA a2 = creator2.createProductA(); AbstractProductB b1 = creator1.createProductB(); AbstractProductB b2 = creator2.createProductB(); // 业务逻辑从这里开始。。。。 } }
-
优点
- 封装性:实现类不是由高层模块关心,而是由工厂类负责创造
- 产品族的约束为非公开状态
-
缺点
- 产品族扩展很困难,需要修改所有类,横向扩展容易,纵向扩展困难
4. 建造者模式
-
定义
- 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的标识
-
通用源码
/** * 产品类-实现模板方法模式 * * @author duogui.zq * @date 2019/2/21 */ public class Product { public void doSomething() { // 独立业务逻辑 } } /** * 抽象建造者-规范产品的组建 * * @author duogui.zq * @date 2019/2/21 */ public abstract class Builder { /** * 设置产品的不同部分,已获得不同的产品 */ public abstract void setPart(); /** * 建造产品 * * @return */ public abstract Product buildProduct(); } /** * 建造者 有多少个产品就有多少个建造者,这些产品类具有相同的接口或者抽象类 * * @author duogui.zq * @date 2019/2/21 */ public class ConcreteProduct extends Builder { private Product product = new Product(); @Override public void setPart() { } @Override public Product buildProduct() { return product; } } /** * 导演类 * * @author duogui.zq * @date 2019/2/21 */ public class Director { private Builder builder = new ConcreteProduct(); public Product getProduct() { builder.setPart(); /** * 设置不同的零件,产生不同的产品 */ return builder.buildProduct(); } }
5. 原型模式
-
定义
- 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
- 核心方法:clone方法
-
通用源码:
/** * 原型模式 * * @author emma_zhang * @date 2019/2/26 */ public class PrototyprClass implements Cloneable { @Override public PrototyprClass clone() { PrototyprClass prototyprClass = null; try { // prototyprClass = (PrototyprClass) super.clone(); }catch (CloneNotSupportedException e) { // 异常处理 } return prototyprClass; } }
-
使用场景
- 需要在一个循环体内产生多个对象时
- 根据一个对象产生多个对象,并且需要对多个对象进行不同的修改时
-
注意事项
- 执行clone操作时构造函数是不会进行执行的,Object类中的clone方法的原理是从内存中(具体是从堆内存中)以二进制流的方法进行拷贝,重新分配一个内存块,那构造函数就不会被执行
- 加final关键字的成员变量不能进行clone
-
深拷贝和浅拷贝
- 浅拷贝:只拷贝本对象,其对象内部的数组,引用对象等都不拷贝,还是指向原生对象的内部元素地址,clone就是浅拷贝,原生类型,类似int,long,char等都会被拷贝
- 深拷贝:完全的拷贝
-
深拷贝的实例
/** * 深拷贝 * * @author emma_zhang * @date 2019/2/26 */ public class DeepClone implements Cloneable { private ArrayList<String> list = new ArrayList<>(); @Override public DeepClone clone() { DeepClone deepClone = null; try { deepClone = (DeepClone)super.clone(); deepClone.list = (ArrayList<String>)this.list.clone(); } catch (CloneNotSupportedException ex) { ex.printStackTrace(); } return deepClone; } }