行为型
解释器模式
不解释
模板方法模式
有些时候,业务可能需要经历很多个步骤来完成, 比如我们生病了在医院看病,首先是去门诊挂号,然后等待叫号,然后是去找医生看病,确定病因后,就根据医生的处方去前台开药,最后付钱。 这一整套流程看似是规规矩矩的,但是在这其中,某些步骤并不是确定的,比如医生看病这一步,由于不同的病因,可能会进行不同的处理,最后开出来的药方也会不同,所以,整套流程中,有些操作是固定的,有些操作可能需要根据具体情况而定。
在我们的程序中也是如此,可能某些操作是固定的,我们就可以直接在类中对应方法进行编写,但是可能某些操作需要视情况而定,由不同的子类实现来决定,这时,我们就需要让这些操作由子类来延迟实现了。现在我们就需要用到模板方法模式。
java
/**
* 抽象诊断方法,因为现在只知道挂号和看医生是固定模式,剩下的开处方和拿药都是不确定的
*/
abstract class AbstractDiagnosis {
public abstract void fallIll();
public void test() {
this.fallIll();
System.out.println("1 >> 先挂号");
System.out.println("2 >> 等待叫号");
//由于现在不知道该开什么处方,所以只能先定义一下行为,然后具体由子类实现
//大致的流程先定义好就行
this.prescribe();
//开药同理
this.medicine();
}
//开处方操作根据具体病症决定了
public abstract void prescribe();
//拿药也是根据具体的处方去拿
public abstract void medicine();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
现在我们定义好了抽象方法,只是将具体的流程先定义出来了,但是部分方法需要根据实现决定:
java
/**
* 感冒相关的具体实现子类
*/
class ColdDiagnosis extends AbstractDiagnosis {
@Override
public void fallIll() {
System.out.println("0 >> 感冒了");
}
@Override
public void prescribe() {
System.out.println("3 >> 一眼丁真,鉴定为假,这不是感冒,纯粹是想摆烂");
}
@Override
public void medicine() {
System.out.println("4 >> 开点头孢回去吃吧");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
责任链模式
责任链模式也非常好理解,比如我们的钉钉审批,实际上就是一条流水线一样的操作,由你发起申请,然后经过多个部门主管审批,最后才能通过,所以你的申请表相当于是在一条责任链上传递。当然除了这样的直线型责任链之外,还有环形、树形等。
这里我们就使用责任链模式来模拟一个简单的面试过程,我们面试也是一面二面三面这样走的流程,这里我们先设计一下责任链上的各个处理器:
java
abstract class Handler {
//这里我们就设计责任链以单链表形式存在,这里存放后继节点
protected Handler successor;
//拼接后续节点
public Handler connect(Handler successor) {
this.successor = successor;
//这里返回后继节点,方便我们一会链式调用
return successor;
}
public void handle() {
//由不同的子类实现具体处理过程
this.doHandle();
Optional
.ofNullable(successor)
//责任链上如果还有后继节点,就继续向下传递
.ifPresent(Handler::handle);
}
//结合上节课学习的模板方法,交给子类实现
public abstract void doHandle();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
因为面试有很多轮,所以我们这里创建几个处理器的实现:
java
class FirstHandler extends Handler {
//用于一面的处理器
@Override
public void doHandle() {
System.out.println("============= 白马程序员一面 ==========");
}
}
class SecondHandler extends Handler {
@Override
public void doHandle() {
System.out.println("============= 白马程序员二面 ==========");
}
}
class ThirdHandler extends Handler{
@Override
public void doHandle() {
System.out.println("============= 白马程序员三面 ==========");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
开始面试
java
public static void main(String[] args) {
Handler handler = new FirstHandler(); //一面首当其冲
handler
.connect(new SecondHandler()) //继续连接二面和三面
.connect(new ThirdHandler());
handler.handle(); //开始面试
}
1
2
3
4
5
6
7
2
3
4
5
6
7
命令模式
比如现在我们有很多的类,彩电、冰箱、空调、洗衣机、热水器等,既然现在我们要通过一个遥控器去控制他们,那么我们就需要将控制这些电器的指令都给设计好才行,并且还不能有太强的关联性。
所有的电器肯定需要通过蓝牙或是红外线接受遥控器发送的请求,所以所有的电器都是接收者:
java
interface Receiver {
//具体行为,这里就写一个算了
void action();
}
//指令抽象,不同的电器有指令
abstract class Command {
private final Receiver receiver;
//指定此命令对应的电器(接受者)
protected Command(Receiver receiver) {
this.receiver = receiver;
}
//执行命令,实际上就是让接收者开始干活
public void execute() {
receiver.action();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
java
//遥控器只需要把我们的指令发出去就行了
class Controller {
public static void call(Command command) {
command.execute();
}
}
class AirConditioner implements Receiver {
@Override
public void action() {
System.out.println("空调已开启,呼呼呼");
}
}
class OpenCommand extends Command {
public OpenCommand(AirConditioner airConditioner) {
super(airConditioner);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
通过这种方式,遥控器这个角色并不需要知道具体会执行什么,只需要发送命令即可,遥控器和电器的关联性就不再那么强了。
迭代器模式
不解释
中介者模式
比如我们想要去外面租房,但是我们怎么知道哪里有可以租的房子呢?于是我们就会上各大租房APP上去找房源,同样的,如果我们现在有房子需要出租,我们也不知道谁会想要租房子,同样的我们也会把房子挂在租房APP上展示,而当我们去租房时或是出租时,就会有一个称为中介的人来跟我们对接,实际上也是一种中介的模式。
java
class Mediator { //房产中介
//在出售的房子需要存储一下
private final Map<String, String> userMap = new HashMap<>();
//出售房屋的人,需要告诉中介他的房屋在哪里
public void register(String address, String user){
userMap.put(address, user);
}
//通过此方法来看看有没有对应的房源
public String find(String address){
return userMap.get(address);
}
}
class User { //用户可以是出售房屋的一方,也可以是寻找房屋的一方
String name;
String tel;
public User(String name, String tel) {
this.name = name;
this.tel = tel;
}
public User find(String address, Mediator mediator){ //找房子的话,需要一个中介和你具体想找的地方
return mediator.find(address);
}
@Override
public String toString() {
return name+" (电话:"+tel+")";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
中介者模式优化了原有的复杂多对多关系,而是将其简化为一对多的关系,更容易理解一些。
java
public class MediatorModeMain {
public static void main(String[] args) {
//出租人
User user0 = new User("刘女士", "10086");
//找房人
User user1 = new User("李先生", "10010");
Mediator mediator = new Mediator(); //我是黑心中介
//先把房子给中介挂上去
mediator.register("上海静安汶水路白马程序员", user0);
//开始找房子
user1.find("上海静安汶水路下硅谷", mediator);
//开始找房子
user1.find("上海静安汶水路白马程序员", mediator);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
备忘录模式
观察者模式
状态模式
策略模式
too 简单,用得too 多 ,no 想多say