设计模式

类型 设计模式 特点
创建型模式 工厂方法模式
抽象工厂模式
单例模式 类只能存在一个对象实例
建造者模式
原型模式
解构型模式 适配器模式
装饰器模式
代理模式
外观模式
桥接模式
组合模式
享元模式
行为型模式 策略模式
模板方法模式(多态) 抽象类, 通用组件
观察者模式
迭代子模式
责任链模式
命令模式
备忘录模式
状态模式
访问者模式
中介者模式
解释器模式

单例模式Singleton

保证某个类只能存在一个对象实例, 并且该类只提供一个取得其对象实例的方法

要求

  • 构造器私有化, 并在内部创建对象实例
  • 提供静态方法来获取该唯一对象实例
  • 静态方法只能调用静态属性, 所以该对象实例也是静态的

饿汉式

不管项目中是否需要使用到该实例对象, 一开始便创建实例对象

public class Bank {
    private String name;
    private String address;

    private static Bank instance = new Bank();

    private Bank() {
    }

    public static Bank getInstance() {
        return instance;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    public Bank setName(String name) {
        this.name = name;
        return this;
    }

    public Bank setAddress(String address) {
        this.address = address;
        return this;
    }

    @Override
    public String toString() {
        return "Bank{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public static void main(String[] args) {

//        验证方式一
        Bank.getInstance().setName("花旗银行").setAddress("欧洲");
        System.out.println(Bank.getInstance());
//        验证方式二
        Bank bank01 = Bank.getInstance();
        Bank bank02 = Bank.getInstance();
        System.out.println(bank01 == bank02);
    }
}

懒汉式

一开始并不急着创建对象, 同时调用方法时需要判断实例对象是否为null

// 线程不安全的懒汉式
public class Order {
    private Integer no;
    private String name;
    private Integer mount;

    /**
     * 一开始并不急着创建对象
     */
    private static Order instance = null;

    private Order() {
    }

    public static Order getInstance() {
//        需要判断当前实例对象是否为null, 否则此时每次调用都会new一个Order对象, 那样就不是单例模式
        if (instance != null) {
            return instance;
        }
        instance = new Order();
        return instance;
    }
}
//线程安全的懒汉式
public class OrderSafe {
    private Integer no;
    private String name;
    private Integer mount;

    private static OrderSafe instance = null;
    private OrderSafe() {
    }

    //只是对获取实例对象的方法使用synchronized来修饰
    public static synchronized OrderSafe getInstance() {
        if (instance != null) {
            return instance;
        }
        instance = new OrderSafe();
        return instance;
    }

    //方式一的等价写法, 静态方法需要使用 类名.class
    public static OrderSafe getInstance() {
        synchronized(OrderSafe.class){
            if (instance != null) {
                return instance;
            }
            instance = new OrderSafe();
            return instance;
        }
    }

    //方式二, 提高返回的效率, 需要理解为什么有效率提升
    public static OrderSafe getInstance() {
        if(instance == null){
            synchronized(OrderSafe.class){
                if (instance != null) {
                    return instance;
                }
                instance = new OrderSafe();
                return instance;
            }            
        }
    }    
}

应用场景

  • 网站的计数器
  • 应用程序的日志应用
  • 数据库连接池
  • 读取配置文件的类
  • Application进程
  • Windows中的任务管理器Task Manager
  • Windows中的回收站Recycle Bin

模板方法模式Template Method

抽象类的应用

功能内部的一部分是确定的, 另外一部分是不确定的, 将不确定的部分暴露出去, 让子类去实现这部分. 函数调用就是最简单的模板方法

能不能实现动态的模板方法呢? 目前的模板方法和工厂方法存在相同的问题. 能不能动态的创建一个方法, 然后让模板函数去执行.

代理模式Proxy

接口的应用

应用场景

  • 安全代理: 屏蔽对真实角色的直接访问
  • 远程代理: 通过代理类处理远程方法调用
  • 延迟加载: 先加载轻量级的代理对象, 真正需要再加载真实的对象

分为静态代理和动态代理

静态代理

针对一个接口就需要写一个代理类

interface Rent {
    /**
     * 租房
     */
    void rent();
}

/**
 * 被代理类
 */
class Customer implements Rent {

    /**
     * 租房
     */
    @Override
    public void rent() {
        System.out.println("租客: 要求房租每月不超过1000");
    }
}


/**
 * 代理类, 并在其中通过多态的方式接收被代理类对象
 */
class Company implements Rent {

    Rent rentObject;

    /**
     * 提供一个构造器, 接收请求的对象
     *
     * @param rentObject 请求租房的对象, 通过接口和多态的方式进行传递
     */
    public Company(Rent rentObject) {
        this.rentObject = rentObject;
    }

    /**
     * 租房
     */
    @Override
    public void rent() {
        ready();
        rentObject.rent();
        transaction();
    }

    private void transaction() {
        System.out.println("双方签订合同");
    }

    private void ready() {
        System.out.println("中介公司进行一些准备工作, 约谈房东");
    }
}

动态代理

  • 代理类和被代理类实现同一套接口
  • 通用的一个代理类工厂可以对应多个被代理类, 根据被代理类运行时实现的接口去动态创建代理类

工厂模式

具体的需求案例

  1. 披萨的种类很多
  2. 披萨的制作流程比较固定
  3. 完成披萨的订购

无工厂模式

简单工厂模式

工厂方法模式

抽象工厂模式


   转载规则


《》 熊水斌 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
面向对象类是抽象的概念, 对象是具体的实例 Java类及类成员public class Person { private String name; private Integer age; static {
2022-11-11
下一篇 
JDBC阶段错误处理MySQL 8.0+版本 问题一问题描述在进行数据库连接时, 连接信息都已经”正确”配置, 结果报错 java.sql.SQLException: Access denied for user '24563
2022-11-11
  目录