设计模式
| 类型 | 设计模式 | 特点 |
|---|---|---|
| 创建型模式 | 工厂方法模式 | |
| 抽象工厂模式 | ||
| 单例模式 | 类只能存在一个对象实例 | |
| 建造者模式 | ||
| 原型模式 | ||
| 解构型模式 | 适配器模式 | |
| 装饰器模式 | ||
| 代理模式 | ||
| 外观模式 | ||
| 桥接模式 | ||
| 组合模式 | ||
| 享元模式 | ||
| 行为型模式 | 策略模式 | |
| 模板方法模式(多态) | 抽象类, 通用组件 | |
| 观察者模式 | ||
| 迭代子模式 | ||
| 责任链模式 | ||
| 命令模式 | ||
| 备忘录模式 | ||
| 状态模式 | ||
| 访问者模式 | ||
| 中介者模式 | ||
| 解释器模式 |
单例模式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("中介公司进行一些准备工作, 约谈房东");
}
}
动态代理
- 代理类和被代理类实现同一套接口
- 通用的一个代理类工厂可以对应多个被代理类, 根据被代理类运行时实现的接口去动态创建代理类
工厂模式
具体的需求案例
- 披萨的种类很多
- 披萨的制作流程比较固定
- 完成披萨的订购
无工厂模式