设计模式

创建型模式

解决对象创建的问题

单例模式

一个类只创建一个对象,作用:1.处理资源冲突访问 2.表示全局唯一类(比如配置信息类、连接池类、ID生成器类)

缺点:

  1. 对OOP特性支持不好
  2. 会隐藏类之间的依赖关系
  3. 对代码的拓展性不好
  4. 对代码的可测试性不好
  5. 不支持有参数的构造函数

饿汉式

在类加载的时候就把静态实例创建好,线程安全,不支持延时加载

1
2
3
4
5
6
7
8
9
10
11
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static final IdGenerator instance = new IdGenerator();
private IdGenerator() {}
public static IdGenerator getInstance() {
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}

懒汉式

需要实例的时候再加载,支持延时加载,但因为要加synchronized,并发度低

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator() {}
public static synchronized IdGenerator getInstance() {
if (instance == null) {
instance = new IdGenerator();
}
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}

双重检测

既支持延时加载,也支持高并发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator() {}
public static IdGenerator getInstance() {
if (instance == null) {
synchronized(IdGenerator.class) { // 此处为类级别的锁
if (instance == null) {
instance = new IdGenerator();
}
}
}
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}

静态内部类

既保证线程安全,也能延时加载

1
2
3
4
5
6
7
8
9
10
11
12
13
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private IdGenerator() {}
private static class SingletonHolder{
private static final IdGenerator instance = new IdGenerator();
}
public static IdGenerator getInstance() {
return SingletonHolder.instance;
}
public long getId() {
return id.incrementAndGet();
}
}

枚举

利用枚举的唯一性,保证了线程安全

1
2
3
4
5
6
7
public enum IdGenerator {
INSTANCE;
private AtomicLong id = new AtomicLong(0);
public long getId() {
return id.incrementAndGet();
}
}

工厂模式

用一个工厂类来创建对象,可以对创建对象的逻辑进行控制

优点:1. 封装变化

  1. 代码复用
  2. 隔离复杂性
  3. 控制复杂度

建造者模式

在创建对象时使用set去初始化对象,用build方法来进行逻辑校验并创建对象

适合用于构造参数较多的对象

工厂模式适合创建类型相似的对象,建造者模式可以创建不同复杂的对象

原型模式

通过拷贝已有对象来创建新对象

浅拷贝:只会复制索引,不会复制数据,拷贝前后的对象共享一份数据,对可变对象来说,有数据被修改的风险,除非操作非常耗时,不然不推荐使用

深拷贝:既会复制索引,也会复制数据,得到一份独立的对象

结构型模式

解决类或对象的组合或组装问题

代理模式

引入代理类,给原始类附加功能,可以实现同一个接口,也可以通过继承的方式

用于开发业务系统的非功能性需求(监控、统计、鉴权、限流、事务、幂等、日志)

桥接模式

把骨架代码和具体实现解藕

装饰器模式

用于解决继承关系过于复杂的情况

装饰类和原始类继承同一个父类,通过组合嵌套多个装饰类来加强功能

适配器模式

把不兼容的接口转为兼容的接口

门面模式

给系统提供一组统一的接口让系统更易使用

封装系统的底层实现,隐藏系统的复杂性,或者把多个接口封装成一个,减少通信消耗

Tomcat服务器中有使用到

组合模式

把对象组织成树状,通过递归简化代码

享元模式

共享不可变对象,一处实例,多处引用,可以节省内存

Java中的Integer在-128~127之间相同的值使用的是享元(同一个对象),String相同的字符串也是享元

行为型设计模式

解决类或对象之间交互的问题

观察者模式

一个被观察者对应多个观察者,被观察者发生改变时所有观察者会被通知

模板模式

定义一个算法骨架,在子类中具体实现

秒杀项目:接口->抽象类->实现类

策略模式

定义一些策略类,让它们可以相互替换,可以减少冗长的if-else语句

职责链模式

多个处理器依次处理一个请求

拦截器、过滤器

状态模式

实现状态机

迭代器模式

用来遍历集合对象,需要实现三种方法:hasNext()、currentItem()、next()

遍历的时候不能增删元素

访问者模式

解藕对象和操作,允许一个或多个操作应用到一组对象上

备忘录模式

存储快照,便于恢复(如撤销)

命令模式

把函数封装成对象,控制命令的执行

解释器模式

根据一定规则解读代码,把语法解析的工作拆分成不同的小类

中介模式

把多对多的对象关系通过一个中介转换成一对多