设计模式复习【2】- 创建类模式

1. 单例模式

  1. 定义

    • 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
  2. 代码

    /**
    * 单例模式-饿汉形式
    * @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;
    }
    }
    

      

  3. 使用场景

    • 要求生成唯一序列化的环境
    • 在整个项目中需要一个共享访问或者共享数据点
    • 创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源
    • 需要定义大量的静态变量和静态方法(工具类)的环境

2. 工厂方法模式

  1. 定义

    • 定义一个用于创建对象的接口,让子类决定实例化哪一个类
    • 工厂方法使一个类的实例化延迟到其子类
  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);
        // 继续业务处理
    }
    }
    

      

  3. 应用场景

    • new一个对象的替代品
    • 需要灵活的,可扩展的框架时,考虑使用工厂方法模式
  4. 扩展

    • 简单工厂模式:将ConcreteCreator中改为静态【static】方法,同时去掉抽象类,简化了类的创建过程
    • 升级为多个工厂方法:一个具体类对应一个工厂

3. 抽象工厂模式

  1. 定义

    • 为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类
    • 在场景类中,没有任何一个方法与实现类有关系,对于一个产品来说,我们只要知道它的工厂方法就可以直接产生一个产品对象,无须关系它的实现类
  2. 通用源码

    /**
    * 抽象产品类
    *
    * @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();
    
        // 业务逻辑从这里开始。。。。
    }
    }
    

      

  3. 优点

    • 封装性:实现类不是由高层模块关心,而是由工厂类负责创造
    • 产品族的约束为非公开状态
  4. 缺点

    • 产品族扩展很困难,需要修改所有类,横向扩展容易,纵向扩展困难

4. 建造者模式

  1. 定义

    • 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的标识
  2. 通用源码

    /**
    * 产品类-实现模板方法模式
    *
    * @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. 原型模式

  1. 定义

    • 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
    • 核心方法:clone方法
  2. 通用源码:

    /**
    * 原型模式
    *
    * @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;
    }
    }
    

      

  3. 使用场景

    • 需要在一个循环体内产生多个对象时
    • 根据一个对象产生多个对象,并且需要对多个对象进行不同的修改时 
  4. 注意事项

    • 执行clone操作时构造函数是不会进行执行的,Object类中的clone方法的原理是从内存中(具体是从堆内存中)以二进制流的方法进行拷贝,重新分配一个内存块,那构造函数就不会被执行
    • 加final关键字的成员变量不能进行clone
  5. 深拷贝和浅拷贝

    • 浅拷贝:只拷贝本对象,其对象内部的数组,引用对象等都不拷贝,还是指向原生对象的内部元素地址,clone就是浅拷贝,原生类型,类似int,long,char等都会被拷贝
    • 深拷贝:完全的拷贝
  6. 深拷贝的实例

    /**
    * 深拷贝
    *
    * @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;
    }
    }
    

      

 

posted @ 2019-03-09 11:37  emma_zhang  阅读(189)  评论(0编辑  收藏  举报