
前言
昨天讲了六大原则,今天就进入设计模式的正题了。
思维导图

创建型设计模式,顾名思义就是与对象的创建相关。
单例模式
定义:保证一个类仅有一个实例,并提供用于一个访问它的全局访问点。

5种写法及其优缺点
(1) 饿汉模式
public class Singleton {
    private static Singleton instance = new Singleton();
    public static Singleton getInstance(){
        return instance;
    }
} 在类加载时就已经完成了初始化。
优点:1. 保障了线程同步的问题;2. 获取对象的效率高。
缺点:1. 降低了类加载时速度;2. 如果一直不使用,会内存的浪费。
(2) 懒汉模式
- 线程不安全 - public class Singleton { private static Singleton instance; public static Singleton getInstance(){ if(instance == null) instance = new Singleton(); return instance; } }- 缺点:存在线程同步问题 
- 线程安全 - public class Singleton { private static Singleton instance; public static synchronized Singleton getInstance(){ if(instance == null) instance = new Singleton(); return instance; } }- 缺点:每一次都需要同步,存在一定的开销问题。 
懒汉模式相较于饿汉模式,不会存在不使用的问题。虽然不再在加载时消耗资源,但是实例化时同样会有一定的时间开销。
(3) 双重检查模式/DCL
public class Singleton {
    private volatile static Singleton instance;
    public static  Singleton getInstance(){
        if(instance == null) {
            synchronized (Singleton.class){
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
} 使用volatile关键词是对正确性的一种保障。
相较于懒汉模式而言,这又是一种升级。因为不在将synchronized套在了函数上,也就不会每次调用都对整个函数同步了,提高了资源的利用率。但是同样存在失效的情况。
失效案例
(4) 静态内部类单例模式
public class Singleton {
    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
    private static class SingletonHolder {
        private volatile static Singleton instance = new Singleton();
    }
} 这是最常用的方法,也是对DCL的一种升级。
优缺点和前面都差不多,就不再复述了。
(5) 枚举单例模式
public enum  Singleton {
    INSTANCE;  
} 这是一种一般不常用的方法,但是能够保障线程同步。
简单工厂模式
定义:又称静态工厂模式,是由一个工厂对象决定创建出那一种产品类的实例。

既然是一个工厂就举一个工厂的例子。
一般来说的工厂模式都是这样的: 客户  -->  工厂  -->  产品
所以产生了三个类
/**
 * 工厂类
 */
public class Factory {
    public static Product product(String type){
        Product product = null;
        switch (type){
            case "鸡翅":
                product = new ChickenWing();
                break;
            case "汉堡":
                product = new Hamburger();
                break;
        }
        return product;
    }
}
/**
 * 抽象产品类
 */
public abstract class Product {
    public abstract void finish();
}
/**
 * 具体产品类
 */
public class Hamburger extends Product {
    @Override
    public void finish() {
        System.out.println("汉堡制作完成");
    }
}
public class ChickenWing extends Product {
    @Override
    public void finish() {
        System.out.println("鸡翅制作完成");
    }
} 三个类已经完成了对应,就跟你在肯德基吃饭一样,告诉他一个名字,他就开始生产。
优点:根据参数获得实例,降低了耦合度。
缺点:不利于扩展功能,因为工厂从一开始就知道能加载的有什么。
使用场景:(1) 工厂负责创建的对象较少;(2)客户只需要知道想要什么,不用关心怎么生成的时候。
工厂方法模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法将类的实例化放到子类中实现。

工厂模式中的四个角色:
- Product:产品抽象类
- Factory:工厂抽象类,返回Product对象
- ConcreteProduct:具体产品类
- ConcreteFactory:具体工厂类
 其实就是对简单工厂方法的一种升级,因为在简单工厂方法中,只有产品这一层被抽象出来了。而工厂方法是把工厂也抽象出来。
 所以以下代码是对简单工厂方法的一种改进。/** * 抽象工厂类 */ public abstract class Factory { public abstract <T extends Product> T product(Class<T> clazz); }
/**
- 具体工厂类
- /
 public class KFC extends Factory {
 @Override
 public <t extends="" product=""> T product(Class<t> clazz) {Product product = null; try{ product = (Product) Class.forName(clazz.getName()).newInstance(); }catch (Exception e){ e.printStackTrace(); } return (T) product;}
 }使用反射机制,也就解决了简单工厂中分支可能存在增加的问题了。 </t></t>
建造者模式
讲一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。

四个角色:
- Director:导演类,将工作按顺序完成。 
- Builder:生成抽象类,生产产品的模版,具体操作由子类完成。 
- ConcreteBuilder:生成具体类。 
- Product:产品类。 
 跟简单工厂不一样,这一次的主角变成了肯德基里服务的店员们了,他们负责完成汉堡制作的各项流程,而- Builder只是说明要干什么事情。- /** * 导演类 */ public class Director { Builder builder; Director(Builder builder){ this.builder = builder; } public Hamburger create(String meat, String vegetable, String bread){ builder.cookBread(bread); builder.cookMeat(meat); builder.cookVegetable(vegetable); return builder.finish(); } }
/**
- Builder抽象类
- /
 public abstract class Builder {
 public abstract void cookMeat(String meat);
 public abstract void cookBread(String bread);
 public abstract void cookVegetable(String vegetable);
 public abstract Hamburger finish();
 }
/**
- Builder类 
- / 
 public class ChickenHamburgerBuilder extends Builder{- private Hamburger hamburger = new Hamburger(); - @Override 
 public void cookMeat(String meat) {- hamburger.setMeat(meat); - } - @Override 
 public void cookBread(String bread) {- hamburger.setBread(bread); - } - @Override 
 public void cookVegetable(String vegetable) {- hamburger.setVegetable(vegetable); - } - @Override 
 public Hamburger finish() {- return hamburger; - } 
 }
/**
- 产品类 
- / 
 public class Hamburger {
 private String vegetable;
 private String meat;
 private String bread;- // 以下省略Getter 和 Setter方法 
 }
 ```

 京公网安备 11010502036488号
京公网安备 11010502036488号