23种设计模式-五种创建型模型

Interview / 2020-05-14

分类

  • 创建型模式(5):将对象的创建和使用分离
    • 单例
    • 原型
    • 工厂方法
    • 抽象工厂
    • 建造者
  • 结构型模型(7):类或者对象以怎样的结构组成一个大的系统
    • 代理
    • 适配器
    • 桥接
    • 装饰
    • 外观
    • 享元
    • 组合
  • 行为型模型(11):类或者对象之间怎样协作完成任务,怎样分配职责
    • 模板方法
    • 策略
    • 命令
    • 职责链
    • 状态
    • 观察者
    • 中介者
    • 迭代器
    • 访问者
    • 备忘录
    • 解释器

其中工厂方法,适配器,模板方法,解释器属于是用于类之间使用的设计模式,其余的属于对象使用的设计模式

创建型模型

关注怎样创建对象,让对象的创建和使用分离,用户只关心对象的使用,不在关注对象的创建

单例模式(Singleton)

类只能创建一个对象,构造函数为私有的

特点:

  • 类只能创建一个对象
  • 对象由类自己创建
  • 单例类对外只有一个全局访问点

举例:

  • 数据库连接池
  • web配置
  • 日志对象

实现

1.懒汉式单例模式

类加载时没有创建对象,第一次使用时创建对象

package com.singLeton;

/**
 * @Author redarm
 * @Date 2020/5/17 12:59 下午
 **/
public class LazySingLeton {

    private static volatile LazySingLeton lazySingLeton = null;

    private LazySingLeton(){

    }

    public static synchronized LazySingLeton getInstance(){

        if (lazySingLeton == null){
            lazySingLeton = new LazySingLeton();
        }

        return lazySingLeton;
    }
}

2.饿汉单例模式

加载类时就创建单例对象

package com.singLeton;

/**
 * @Author redarm
 * @Date 2020/5/17 1:03 下午
 **/
public class HungrySingLeton {

    private static final HungrySingLeton instance = new HungrySingLeton();

    private HungrySingLeton(){

    }

    public static HungrySingLeton getInstance(){
        return instance;
    }
}

应用:

  • 要求只有一个对象
  • 对象需要被共享
  • 对象反复的创建和销毁时

原型模式(Prototype)

对象的创建不是new,而是复制clone一个对象

实现

实现Cloneable接口的clone方法

package com.DesignPatterns.protoType;

/**
 * @Author redarm
 * @Date 2020/5/17 2:43 下午
 * 原型模式
 **/
public class ProtoType{

    public static void main(String[] args) throws CloneNotSupportedException {

        Student student1 = new Student("liu");

        Student student2 = student1.clone();

        System.out.println(student1.toString() + "  :  " + student2.toString());
    }
}

class Student implements Cloneable{

    private String name;

    public Student(String name){
        this.name = name;
    }

    public Student(){
        this.name = null;
    }

    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student)super.clone();
    }

    @Override
    public String toString() {
        return "name: " + this.name;
    }
}

clone:完全复制复制对象

应用:

  • 对象之间相同,或者个别属性不同

工厂方法模型(FactoryMethod)

通过工厂创建对象,只要直到工厂名称就能创建对象,不需要知道创建的过程,而且可以增加对象的种类,同时也增加了对应的工厂类

实现:

  • 产品接口
  • 产品实现
  • 工厂接口
  • 工厂实现

动物接口

package com.DesignPatterns.factoryMethod;

/**
 * @Author redarm
 * @Date 2020/5/17 6:21 下午
 * 工厂方法模型
 **/
public interface Animal {

    void getName();
}

动物实现

package com.DesignPatterns.factoryMethod;

/**
 * @Author redarm
 * @Date 2020/5/17 6:22 下午
 **/
public class Dog implements Animal {

    private String name;

    public Dog(){
        this.name = "dog";
    }

    @Override
    public void getName() {
        System.out.println("I am a " + this.name);
    }
}

package com.DesignPatterns.factoryMethod;

/**
 * @Author redarm
 * @Date 2020/5/17 6:23 下午
 **/
public class Horse implements Animal {

    private String name;

    public Horse(){
        this.name = "horse";
    }

    @Override
    public void getName() {
        System.out.println("I am a " + this.name);
    }
}

工厂接口

package com.DesignPatterns.factoryMethod;

/**
 * @Author redarm
 * @Date 2020/5/17 6:24 下午
 **/
public interface AnimalFarm {

    Animal getAnimal();
}

工厂实现

package com.DesignPatterns.factoryMethod;

/**
 * @Author redarm
 * @Date 2020/5/17 6:26 下午
 **/
public class DogFarm implements AnimalFarm {
    @Override
    public Animal getAnimal() {
        return new Dog();
    }
}

package com.DesignPatterns.factoryMethod;

/**
 * @Author redarm
 * @Date 2020/5/17 6:26 下午
 **/
public class HorseFarm implements AnimalFarm {
    @Override
    public Animal getAnimal() {
        return new Horse();
    }
}

测试:

package com.DesignPatterns.factoryMethod;

/**
 * @Author redarm
 * @Date 2020/5/17 6:27 下午
 **/
public class Test {

    public static void main(String[] args) {

        new DogFarm().getAnimal().getName();

        new HorseFarm().getAnimal().getName();
    }
}

应用:

  • 只需知道工厂名,无需知道产品名
  • 工厂中产品种类一样,品牌不一样

抽象工厂模型(AbstractFactory)

当工厂可以生产不同类型的产品时,使用抽象工厂模型

实现

  • 产品接口
  • 实现产品的工厂

动物接口

package com.DesignPatterns.abstractFactory;

/**
 * @Author redarm
 * @Date 2020/5/17 6:43 下午
 * 抽象工厂模型
 **/
public interface Animal {

    void newDog();

    void newHorse();
}

工厂实现

package com.DesignPatterns.abstractFactory;

/**
 * @Author redarm
 * @Date 2020/5/17 6:45 下午
 **/
public class AnimalFactory implements Animal {
    @Override
    public void newDog() {
        System.out.println("I am a Dog");
    }

    @Override
    public void newHorse() {
        System.out.println("I am a Horse");
    }
}

建造者模式(Builder)

对象由多个部件组成,比如电脑对象由CPU,GPC,Board组成

实现:

  • 对象
  • 建造者抽象类
  • 建造者实现(可以多个)
  • 统一管理者

电脑对象:

package com.DesignPatterns.builder;

/**
 * @Author redarm
 * @Date 2020/5/17 7:09 下午
 * 建造者模型
 **/
public class Computer {

    private String CPU;
    private String board;
    private String GPU;

    public String getCPU() {
        return CPU;
    }

    public void setCPU(String CPU) {
        this.CPU = CPU;
    }

    public String getBoard() {
        return board;
    }

    public void setBoard(String board) {
        this.board = board;
    }

    public String getGPU() {
        return GPU;
    }

    public void setGPU(String GPU) {
        this.GPU = GPU;
    }

    @Override
    public String toString() {
        return "CPU: " + this.getCPU() + " GPU: " + this.getGPU() + " Board: " + this.getBoard();
    }
}


建造者抽象和两个实现

package com.DesignPatterns.builder;

/**
 * @Author redarm
 * @Date 2020/5/17 7:11 下午
 **/
public abstract class ComputerBuilder {

    Computer computer = new Computer();

    void setCPU() {

    }

    void setBoard() {

    }

    void setGPU() {

    }

    Computer getComputer(){
        return computer;
    };
}

package com.DesignPatterns.builder;

/**
 * @Author redarm
 * @Date 2020/5/17 7:14 下午
 **/
public class InterComputerBuilderOne extends ComputerBuilder {
    @Override
    public void setCPU() {
        computer.setCPU("i9 9900k");
    }

    @Override
    public void setBoard() {
        computer.setBoard("B360-M");
    }

    @Override
    public void setGPU() {
        computer.setGPU("2080Ti");
    }
}

package com.DesignPatterns.builder;

/**
 * @Author redarm
 * @Date 2020/5/17 7:18 下午
 **/
public class AMDComputerBuilder extends ComputerBuilder {
    @Override
    public void setCPU() {
        computer.setCPU("r5 3600x");
    }

    @Override
    public void setBoard() {
        computer.setBoard("B360-M");
    }

    @Override
    public void setGPU() {
        computer.setGPU("2080Ti");
    }
}

统一管理

package com.DesignPatterns.builder;

/**
 * @Author redarm
 * @Date 2020/5/17 7:17 下午
 **/
public class ComputerManager {

    private ComputerBuilder computerBuilder;

    public ComputerManager(ComputerBuilder computerBuilder){
        this.computerBuilder = computerBuilder;
    }

    public ComputerManager(){
        this.computerBuilder = new InterComputerBuilderOne();
    }

    public Computer newComputer(){
        computerBuilder.setCPU();
        computerBuilder.setGPU();
        computerBuilder.setBoard();

        return computerBuilder.getComputer();
    }

    public Computer newInterComputer(){
        this.computerBuilder = new InterComputerBuilderOne();

        computerBuilder.setBoard();
        computerBuilder.setCPU();
        computerBuilder.setGPU();

        return computerBuilder.getComputer();
    }

    public Computer newAMDComputer(){
        this.computerBuilder = new AMDComputerBuilder();

        computerBuilder.setCPU();
        computerBuilder.setGPU();
        computerBuilder.setBoard();

        return computerBuilder.getComputer();
    }
}

测试

package com.DesignPatterns.builder;

/**
 * @Author redarm
 * @Date 2020/5/17 7:24 下午
 **/
public class Test {

    public static void main(String[] args) {

        ComputerManager computerManager = new ComputerManager();

        Computer InterComputer = computerManager.newInterComputer();

        Computer AMDComputer = computerManager.newAMDComputer();

        System.out.println("Inter: " + InterComputer.toString() + "\nAMD: " + AMDComputer.toString());
    }
}

应用:

  • 对象复制,组件多
  • 每个对象部件组成相同,但是每个部件的实现不同