设计模式-创建型模式

253 阅读3分钟

1.简单工厂模式/静态工厂模式

  • 简介

    用一个专业类(工程类)类负责一种产品的对象创建。根据type创建不同的产品,create()方法是静态的,不属于23中设计模式。

    public static Fruit getFruit(int type){
        if(TYPE_APPLE == type){
            return new Apple();
        } else if(TYPE_ORANGE == type){
           return new Orange("Peter",80);
        } else if(TYPE_BANANA == type){
            return new Banana();
        }
        return null;
    }
    

    Activity.getSystemService()使用了此设计模式。

  • 变通

    多方法工厂,使用者不需要了解具体工厂类的type,只需了解工厂方法名。

     /**
     * 多方法工厂
     * @return
     */
    public static Fruit getFruitApple(){
        return new Apple();
    }
    
    public static Fruit getFruitOrange(){
        return new Orange("Peter",80);
    }
    
    public static Fruit getFruitBanana(){
        return new Banana();
    }
    
  • 优点

    1. 把对象的创建和使用分开;
    2. 集中管理对象的生产过程;
    3. 生产过程发生变化时,使用者不需要再去修改代码。
  • 设计缺陷

    1. 不符合单一职责原则,一个类负责多个产品的创建。

    2. 不符合开闭原则,增加品类时,需要修改已有代码。

2.工厂方法模式

  • 描述

    1.工厂结构类与产品子类一一对应。(单一职责原则)

    2.为增强扩展性,工厂方法抽象成接口。(依赖倒置原则——面向接口编程)

    3.增加品类时,增加工厂子类,不需要修改已有代码。(开闭原则)

  • 类图

  • 工厂方法模式包括四部分

    1.抽象产品类:产品对象统一的基类,或者是同一个接口。

    2.具体的产品类:各个不同产品的实例对象。

    3.抽象工厂类:所有产品工厂的基类,或同一个接口。

    4.具体的工厂子类:负责每一个不同产品对象的实际创建。

3.抽象工厂方法模式

  • 描述

    工厂方法模式的扩展,一个类别的产品有多个系列时,相关联系列的商品,使用同一个工厂生产。

  • 类图

4.建造者模式

创建对象比较复杂时,可使用建造者模式。

  • 类图

5.创建型模式总结(工厂/建造者模式)

  • 原则

    1.解耦,把对象的创建和使用过程分开。

    2.工厂负责对象的创建,包括初始化方法的调用,黑盒创建过程。

    3.面向接口编程:使用者只关注使用,只知接口,不知其实现类。

  • 对比

    1.静态工厂方法:把所有对象的创建都集中在一个类中处理。

    2.工厂方法模式:一个工厂负责一个产品的创建,面向接口。

    3.抽象工厂模式:将同一系列产品的工程合并成一个工厂,负责生产这个系列的产品。关注一系列产品之间的关系。

    4.建造者模式:对象的创建比较复杂时,按步骤一块一块的创建,让创建过程模块化。更关注一个类内部复杂的实现。

6.单例模式

  • 描述

    保证一个类仅有一个实例,并且提供一个访问它的全局访问点。

    1. 为防止实例被创建多个,将构造干事限制为private。
    2. 创建一个类静态变量,持有一个自己的实例。
    3. 通过静态方法对外部提供这一实例。
  • 静态实例初始化方式

    1. 饿汉式

      类加载时,创建静态实例,浪费内存空间。

    2. 懒汉式

      多次判空,双重校验锁。存在双重校验锁失效的情况。

    3. 静态内部类

       public class Singletion{
        private Singletion(){}
    
        public static Singletion getIntanc(){
            return SingletionHolder.sInstance;
        }
    
        /*
         * @Description: 静态内部类
         * @param: null
         * @return:
         * @Author: wanglei
         * @Date: 2021/2/15 12:16
         * @modify: 2021/2/15 12:16
         */
        private static class SingletionHolder(){
            private final static Singletion sInstance = new Singletion();
        }
    }     
    

    第一次加载Singletion类时不会初始化sInstance,这种初始化方式,能够保证线程安全,保证单例对象的唯一性,同时也延迟了单例的实例化。

    JVM类加载实现了线程安全。