设计模式

设计模式

23个设计模式分类

总体来说设计模式分为三大类:

  • 创建型模式,共五种:

工厂方法模式、抽象工厂模式、单例模式、建造者(构造器)模式、原型模式。

  • 结构型模式,共七种:

适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

  • 行为型模式,共十一种:

策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

责任链模式

责任链模式在框架的引用极为广泛, 例如SpringSecurity的过滤器链, Sentinel的插槽(限流, 降级, 系统保护等),他们实现就像一条链子一样 一级一级的往下走。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

建造者(构造器)模式

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,建造者模式是一种对象创建型模式。:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,建造者模式是一种对象创建型模式。

最常见的是Lombok的@Builder注解, 让我们使用流式创建对象。

: 每一个属性对应的方法都,返回Builder本身

  1. 通过一个public static class Builder的内部类,持有要构建对象的所有属性

  2. 设置属性的方法都返回Builder当前实例this,这样可以流式设置属性,用起来更加方便

  3. 提供一个static的Builder方法,方便用户获取Builder对象

  4. 用户通过builder对象自定义设置属性

  5. 提供build方法,创建最终对象

工厂方法模式

适用: 根据条件 判断生成什么对象

简单工厂模式

案例: 我们有一个生产课程对象的工厂(CourseFactory), 根据传入条件生产对象(JavaCourse,GoCourse…)

需求: 我们传入什么则生成什么对象

实现: 可以通过给工厂的create(自定义的创建生产的方法), 传入对象名、类名、字节码对象, 然后生产相对应的实例对象

此时的工厂模式有一个最大的特点就是工厂具体, 产品抽象, 工厂生产是根据条件生产, 只能生产一个类的课程

查看代码测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 生产的工厂
public class CourseFactory {
public ICourse create(Class<?> clazz){ // ICourse: 课程的抽象
try{
if(null != clazz){
return clazz.newInstance();
}
}catch(Exception e){
e.printStackTace();
}
}
}
// 测试
@Test
public void test(){
CourseFactory cf = new CourseFactory();
ICourse course = cf.create(JavaCourse.class);
}

工厂方法模式

产品抽象, 工厂也抽象。

Java课程对应一个Java工厂, Python课程对应一个Python工厂. 在某一个特定的工厂可以根据特定的条件生产特定的产品. 解耦合

例如: List的实现, 可以发现不同的具体实例实现有不同的遍历方法(指: 迭代器). 因为不同的实现, 它们底层的数据结构实现不同, 在LinkedList底层则是链表, ArrayList则是顺序表.

追踪ArrayList的源码中实现的迭代方法Iterator

1
2
3
4
// 这个就是工厂生产产品的方法, 生产了一个用于ArrayList的Itr迭代实例
public Iterator<E> iterator() {
return new Itr();
}
1
2
3
4
5
6
7
8
9
10
11
12
// 继续追踪Itr(), 可以发现next方法
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}

很容易知道, 其实就是一个顺序表的遍历

同理LinkedList遍历也是一样, 通过实现Iterator, 容易知道肯定是链表的遍历

1
2
3
4
5
6
7
8
9
10
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();

lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}

所以有: List的各种实现类, 不同的数据结构实现所实现的迭代器(工厂方法–> 用于生产产品–> 迭代器产品).

在SpringCloud Gateway中, 我们可以看到关键组件有

  • 谓词工厂

用于定义路由规则。谓词工厂接收一个输入(通常是一个HTTP请求),并根据定义的规则返回一个布尔值,指示该请求是否与路由匹配。

1
2
3
4
5
6
7
8
spring:
cloud:
gateway:
routes:
- id: food-service # 路由规则id,自定义,唯一
uri: lb://food-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表
predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务
- Path=/resfood/** # 这里是以请求路径作为判断规则

predicates: 路由断言

现在使用该模式我们可以通过,根据条件创建一个对象, 在以往之前, 只能通过new一个具体对象

其他的案例还有: 1. Feign 2. JDK中的StringBuilder

  • 过滤器工厂