模版方法模式

抽象类定义一组方法的执行顺序,具体的功能由子类来实现。
它仅仅使用了Java的继承机制,但使用非常广泛。
一般多个子类有公有的方法,并且逻辑基本相同的时候使用。

定义

定义一个操作中的算法框架,再将一些步骤延迟到子类中。使得子类可以不改变算法的结构就可以定义该算法的某些特定步骤。

模版方法模式通用类图

实现

基本方法

一些基本的操作,由子类实现具体的逻辑,在模版方法中被调用。

模版方法

模版方法可以有一个或者多个,一般是一个具体的方法,包含了基本方法的调用逻辑。

抽象模版类中包含了一个模版方法goToSchool和三个基本方法toSchool, study, goHome.
这样,每个学生继承该抽象类实现自己逻辑即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class StudentBehavor{
protected abstract void toSchool();
protected abstract void study();
protected abstract void goHome();
public void goToSchool(){
//do something.
toSchool();
// do something.
study();
// do something.
goHome();
// do something.
}

}

应用

优点

  • 封装不变部分,扩展可变部分
    把认为不变的部分算法封装到父类实现,可变部分通过继承来扩展。

  • 提取公共部分代码,便于维护

  • 行为由父类控制,子类实现
    基本方法由子类实现,子类可以扩展增加相应的功能,符合开闭原则。

缺点

在复杂的项目中,增加代码的阅读难度。

责任链模式

责任链模式的核心在链上, 链是有多个处理者组成的。就像流水线上的质检员。

定义

使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

责任链模式通用类图

实现

抽象事件

抽象事件类型表明这类型的事件是需要被处理的。

1
2
3
public interface IEvent {
int getType();
}

具体的事件

不同类型的子类事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class EventClick implements IEvent {
public int getType() {
return 1;
}
}
public class EventEnter implements IEvent {
public int getType() {
return 2;
}
}
public class EventBlank implements IEvent {
public int getType() {
return 3;
}
}

抽象的事件处理器

定义了只有Ievent类型的事件会被处理。

1
2
3
public interface IEventHandler {
boolean check(IEvent event);
}

具体的事件处理器

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
34
public class ClickEventHandler implements IEventHandler {

public boolean check(IEvent event) {
if (event.getType() != 1){
return false;
}
System.out.println("Father check Ok. ");
return true;
}
}

public class EnterEventHandler implements IEventHandler {

public boolean check(IEvent event) {
if (event.getType() == 2) {
System.out.println("Husband Ok.");
return true;
}
return false;
}
}

public class BlankEventHandler implements IEventHandler {

public boolean check(IEvent event) {
if (event.getType() != 3) {
return false;
}

System.out.println("Son Ok");
return true;

}
}

事件处理链

用于组织事件处理器,符合条件的处理器处理完成后或者没有处理器处理都会停止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class EventHandlerChain {
private List<IEventHandler> eventChains = new ArrayList<IEventHandler>();
public void add(IEventHandler eventHandler) {
eventChains.add(eventHandler);
}
public boolean check(IEvent event) {
for (IEventHandler eventChain : this.eventChains) {
if (eventChain.check(event)) {
return true;
}
}
return false;
}

}

Use

可以随意组织责任链的顺序,然后检查需要检查的类型。

1
2
3
4
5
6
7
8
EventHandlerChain chain = new EventHandlerChain();
chain.add(new ClickEventHandler());
chain.add(new EnterEventHandler());
chain.add(new BlankEventHandler());

chain.check(new EventClick());
chain.check(new EventEnter());
chain.check(new EventBlank());

应用

优点

将请求和处理分开。请求着可以不用知道是谁处理的,处理者可以不用知道请求着的全貌。
两者解耦,提高了系统的灵活性。

缺点

性能问题, 最差的情况下,请求从头遍历到尾,链条特别长的时候,性能损耗是个大的问题。
因此在使用的过程中要注意责任链的长短。
调试不方便。

在广告系统中,由不同的事件来触发不同类型的广告时根据责任链模式来处理。
每个Handler可以专注自己的业务处理逻辑。具体Handler还可以抽象一个抽象类,把公用的逻辑写在抽象类里面,每个具体的实现类只负责业务的处理即可(优化为模版方法模式)。