小蜜锋 - 云代码空间
—— 技术宅拯救世界!
设计模式中的行为型模式,包括观察者模式、状态模式、策略模式、模板模式、访问者模式、职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式,本文主要用简单的实例介绍这几种设计模式。
· 观察者模式 - 找工作或观察工作 原文 Observer – Look for a job or observe a job?
· 观察者模式 - 一个简单的Swing GUI例子 原文 Observer – A simple Swing GUI example
· 状态模式 - 当生活困难时要努力工作 原文 State – Work hard when life is hard
· 策略模式 - 如果加速你会得到票吗 原文 Strategy – Will you get a ticket if speeding
· 模板模式 - 测试车辆 原文 Template – Test a vehicle
· 访问者模式 - 访问纽约 原文 Visitor – Visit New York City
· 职责链模式 - 职责链 原文 Chain of responsibility – The responsibility chain
· 命令模式 - 使用不同的命令控制电脑 原文 Command – Use different command to control computer
· 解释器模式 - 解释一些内容 原文 Interpreter – Interpret some context
· 迭代器模式 - 迭代一个对象集合 原文 Iterator – Iterate a collection of objects
· 中介者模式 - 两个同事的交流 原文 Mediator – Mediate two colleagues
· 备忘录模式 - 使用备忘录记录时间旅行 原文 Memento – Use memento to time travel
简单地说,观察者模式=出版者+订阅者。
观察者模式已被用于在GUI动作监听器上。Swing GUI 示例显示了动作监听器如何像观察者一样工作。
下面是一个典型的关于猎头的例子。在这个图中有两个角色 - 猎头和求职者 。求职者订阅猎头,当有一个新的工作机会时猎头会发布招聘消息,求职者就能收到订阅。
类图
Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
//Subject interface.
publicinterfaceSubject {
publicvoidregisterObserver(Observer o);
publicvoidremoveObserver(Observer o);
publicvoidnotifyAllObservers();
}
//Observer interface.
publicinterfaceObserver {
publicvoidupdate(Subject s);
}
//HeadHunter class implements Subject.
importjava.util.ArrayList;
publicclassHeadHunter implementsSubject{
//define a list of users, such as Mike, Bill, etc.
privateArrayList<Observer> userList;
privateArrayList<String> jobs;
publicHeadHunter(){
userList = newArrayList<Observer>();
jobs = newArrayList<String>();
}
@Override
publicvoidregisterObserver(Observer o) {
userList.add(o);
}
@Override
publicvoidremoveObserver(Observer o) {}
@Override
publicvoidnotifyAllObservers() {
for(Observer o: userList){
o.update(this);
}
}
publicvoidaddJob(String job) {
this.jobs.add(job);
notifyAllObservers();
}
publicArrayList<String> getJobs() {
returnjobs;
}
publicString toString(){
returnjobs.toString();
}
}
//JobSeeker is an observer.
publicclassJobSeeker implementsObserver {
privateString name;
publicJobSeeker(String name){
this.name = name;
}
@Override
publicvoidupdate(Subject s) {
System.out.println(this.name + " got notified!");
//print job list
System.out.println(s);
}
}
//Start Point.
publicclassMain {
publicstaticvoidmain(String[] args) {
HeadHunter hh = newHeadHunter();
hh.registerObserver(newJobSeeker("Mike"));
hh.registerObserver(newJobSeeker("Chris"));
hh.registerObserver(newJobSeeker("Jeff"));
//Each time, a new job is added, all registered job seekers will get noticed.
hh.addJob("Google Job");
hh.addJob("Yahoo Job");
}
}
|
JDK中的观察者模式
java.util.EventListener
Swing GUI example
这个例子显示了如何创建一个Swing GUI的例子,并解释为什么它是观察者设计模式的用法的例子。
完整代码
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
|
importjava.awt.BorderLayout;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JTextArea;
publicclassSimpleSwingExample {
publicstaticvoidmain(String[] args) {
JFrame frame = newJFrame("Frame Title");
finalJTextArea comp = newJTextArea();
JButton btn = newJButton("click");
frame.getContentPane().add(comp, BorderLayout.CENTER);
frame.getContentPane().add(btn, BorderLayout.SOUTH);
btn.addActionListener(newActionListener() {
publicvoidactionPerformed(ActionEvent ae) {
comp.setText("Button has been clicked");
}
});
intwidth = 300;
intheight = 300;
frame.setSize(width, height);
frame.setVisible(true);
}
}
|
一步一步的解释
首先,我们需要一个容器像一个Frame,一个Window,或一个Applet,用来展现组件如panels、buttons、text areas等。
1
|
JFrame frame = newJFrame("Frame Title");
|
创建一些组件如面板,按钮,文本等
1
2
|
finalJTextArea comp = newJTextArea();
JButton btn = newJButton("click");
|
添加组件到显示区域,并使用LayoutManager安排其布局。
1
2
|
frame.getContentPane().add(comp,BorderLayout.CENTER);
frame.getContentPane().add(btn, BorderLayout.SOUTH);
|
为按钮添加一个监听器,用来与组件发生的事件交互。也就是要关联组件和用户操作,就添加一个监听器到组件上。
这里的addActionListener方法就是订阅者的注册观察方法。观察者设计模式对于一个完整的例子,查看另一个观察者例子。
1
2
3
4
5
|
btn.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvent ae){
comp.setText("Button has been clicked");
}
});
|
public interface ActionListener extends EventListener
listener 接口用来接收动作事件。该类(这个例子中主要的类)主要关注处理来自事件接口的动作事件,创建该类的对象并使用该组件的addActionListener方法注册组件。动作事件发生时,该对象的actionPerformed方法将被调用。
显示帧
1
2
3
4
|
intwidth = 300;
intheight = 300;
frame.setSize(width, height);
frame.setVisible(true);
|
状态设计模式主要是在运行时改变状态。
状态模式的故事
人们可以生活在不同的经济条件下。他们可以是富人,也可以是穷人。这两种状态 - 穷人和富人 - 可以随时互相转换。例子是:当人很穷时,他们工作非常刻苦,当人和富裕时,他们就可以更多的玩。他们是富是穷取决于他们的生活现状。他们可以通过他们的行动改变自己的生活状态,否则,社会是不公平的。
状态模式的类图
下面是类图。你可以比较这个策略模式 ,以对比他们的不同之处。
状态模式的Java代码
下面的Java示例显示了状态模式是如何工作的。
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
//State classes.
packagecom.programcreek.designpatterns.state;
interfaceState {
publicvoidsaySomething(StateContext sc);
}
classRich implementsState{
@Override
publicvoidsaySomething(StateContext sc) {
System.out.println("I’m rick currently, and play a lot.");
sc.changeState(newPoor());
}
}
classPoor implementsState{
@Override
publicvoidsaySomething(StateContext sc) {
System.out.println("I’m poor currently, and spend much time working.");
sc.changeState(newRich());
}
}
//StateContext class
packagecom.programcreek.designpatterns.state;
publicclassStateContext {
privateState currentState;
publicStateContext(){
currentState = newPoor();
}
publicvoidchangeState(State newState){
this.currentState = newState;
}
publicvoidsaySomething(){
this.currentState.saySomething(this);
}
}
//Main class for testing
importcom.programcreek.designpatterns.*;
publicclassMain {
publicstaticvoidmain(String args[]){
StateContext sc = newStateContext();
sc.saySomething();
sc.saySomething();
sc.saySomething();
sc.saySomething();
}
}
|
结果:
I’m poor currently, and spend much time working. I’m rick currently, and play a lot. I’m poor currently, and spend much time working. I’m rick currently, and play a lot.
策略模式(英文strategy pattern也可叫做policy pattern)
下面是一个关于策略模式的故事。假设Mike开车时,有时会加速行驶,但并不总是加速。当通过有交警的地方,他可能会停下来。有时候警察是非常好的,让他没有任何罚单或一个警告便顺利通过。(这种警察称“NicePolice”。)也有可能是他会被不好的警察拦下并开一张罚单。(我们称这种警察为“HardPolice”。)他并不知道什么样的警察会阻止他,直到他被拦下,只能看情况而定。这正好就是策略模式关注的点。
策略模式类图
策略模式的Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
//Define a interface Strategy, which has one method processSpeeding()
publicinterfaceStrategy {
//defind a method for police to process speeding case.
publicvoidprocessSpeeding(intspeed);
}
//Now we have two kinds of police officers.
publicclassNicePolice implementsStrategy{
@Override
publicvoidprocessSpeeding(intspeed) {
System.out.println("This is your first time, be sure don't do it again!");
}
}
publicclassHardPolice implementsStrategy{
@Override
publicvoidprocessSpeeding(intspeed) {
System.out.println("Your speed is "+ speed+ ", and should get a ticket!");
}
}
//Define a situation in which a police officer will be involved to process speeding.
publicclassSituation {
privateStrategy strategy;
publicSituation(Strategy strategy){
this.strategy = strategy;
}
publicvoidhandleByPolice(intspeed){
this.strategy.processSpeeding(speed);
}
}
//Finally, try the result.
publicclassMain {
publicstaticvoidmain(String args[]){
HardPolice hp = newHardPolice();
NicePolice ep = newNicePolice();
// In situation 1, a hard officer is met
// In situation 2, a nice officer is met
Situation s1 = newSituation(hp);
Situation s2 = newSituation(ep);
//the result based on the kind of police officer.
s1.handleByPolice(10);
s2.handleByPolice(10);
}
}
|
输出是:
Your speed is 10, and should get a ticket! This is your first time, be sure don’t do it again!
你可以比较策略模式和状态模式,他们非常相似。主要的区别是,状态模式是当对象的状态变化时改变对象的行为,而策略模式主要是在不同情况下使用不同的算法。
JDK中的策略模式
Java.util.Collections#sort(List list, Comparator c)
Sort 方法在不同情况下使用不同的Comparator。要知道更多关于Comparator的内容,查看compare Comparator with Comparable。
模板方法设计模式,实现了具体操作的工作流程定义。它允许子类修改某些特定的步骤,但不改变整个工作流的结构。
下面的例子显示了模板方法模式是如何工作的。
类图
Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
//Vehicle.java defines a vehicle and hot it works
packagecom.programcreek.designpatterns.templatemethod;
abstractpublicclassVehicle {
//set to protected so that subclass can access
protectedbooleanstatus;
abstractvoidstart();
abstractvoidrun();
abstractvoidstop();
publicvoidtestYourVehicle(){
start();
if(this.status){
run();
stop();
}
}
}
//Car.java subclass Vehicle and defines concrete methods
packagecom.programcreek.designpatterns.templatemethod;
publicclassCar extendsVehicle {
@Override
voidstart() {
this.status = true;
}
@Override
voidrun() {
System.out.println("Run fast!");
}
@Override
voidstop() {
System.out.println("Car stop!");
}
}
//Truck.java subclass Vehicle and defines concrete methods
packagecom.programcreek.designpatterns.templatemethod;
publicclassTruck extendsVehicle {
@Override
voidstart() {
this.status = true;
}
@Override
voidrun() {
System.out.println("Run slowly!");
}
@Override
voidstop() {
System.out.println("Truck stop!");
}
}
//The testVehicle method only accept a Vehicle, it does not care if it is a car or truck, because they will work in the same way. This is an example of program to interface(P2I).
importcom.programcreek.designpatterns.templatemethod.Car;
importcom.programcreek.designpatterns.templatemethod.Truck;
importcom.programcreek.designpatterns.templatemethod.Vehicle;
publicclassMain {
publicstaticvoidmain(String args[]){
Car car = newCar();
testVehicle(car);
Truck truck = newTruck();
testVehicle(truck);
}
publicstaticvoidtestVehicle(Vehicle v){
v.testYourVehicle();
}
}
|
模板方法模式的实际使用
Spring框架的数据访问对象(DAO)就是采用这种模式 org.springframework.jdbc.core。JdbcTemplate 类有所有常见的与JDBC的工作流程相关的重复代码块,如更新,查询,执行等。
访问者模式是编译器解析时常用的一种设计模式,如Eclipse JDT AST分析器。
在访问者模式中,基本有两个接口 - Visitor 和 Element。
访问者模式的故事
假设游客第一次来到纽约。他想访问的这个城市,并且城市允许他的访问。一旦游客开始参观,它会自动访问一切,当希望去一个博物馆时,他并不需要额外调用一个方法。旅游行为是打包进行的!
访问者模式的类图
访问者模式的步骤
此图显示了访问步骤。
工作过程如下所示:
访问者模式的Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
importjava.util.ArrayList;
interfaceVisitor {
publicvoidvisit(City city);
publicvoidvisit(Museum museum);
publicvoidvisit(Park park);
}
classFirstTimeVisitor implementsVisitor {
@Override
publicvoidvisit(City city) {
System.out.println("I'm visiting the city!");
}
@Override
publicvoidvisit(Museum museum) {
System.out.println("I'm visiting the Museum!");
}
@Override
publicvoidvisit(Park park) {
System.out.println("I'm visiting the Park!");
}
}
interfaceElement {
publicvoidaccept(Visitor visitor);
}
classCity implementsElement {
ArrayList<Element> places = newArrayList<Element>();
publicCity() {
places.add(newMuseum());
places.add(newPark());
}
@Override
publicvoidaccept(Visitor visitor) {
System.out.println("City is accepting visitor.");
visitor.visit(this);
for(Element e : places) {
e.accept(visitor);
}
}
}
classMuseum implementsElement {
@Override
publicvoidaccept(Visitor visitor) {
System.out.println("Museum is accepting visitor.");
visitor.visit(this);
}
}
classPark implementsElement {
@Override
publicvoidaccept(Visitor visitor) {
System.out.println("Park is accepting visitor.");
visitor.visit(this);
}
}
publicclassTestVisitor {
publicstaticvoidmain(String[] args) {
FirstTimeVisitor visitor = newFirstTimeVisitor();
City city = newCity();
city.accept(visitor);
}
}
|
输出:
City is accepting visitor. I’m visiting the city! Museum is accepting visitor. I’m visiting the Museum! Park is accepting visitor. I’m visiting the Park!
JDK中的访问者模式
javax.lang.model.element.AnnotationValue 明显使用访问者模式,但它在常规项目中不是很常用。
职责链设计模式的主要思想是建立一个连锁处理单元,每个单元在满足阈值时处理请求。当链建立完成,如果一个单元不满足阈值时,跳到它的下一个单元继续判断阈值是否满足,如此一步步运行。每个请求都将沿着这条链进行。
责任链类图
责任链的Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
packagedesignpatterns.cor;
abstractclassChain {
publicstaticintOne = 1;
publicstaticintTwo = 2;
publicstaticintThree = 3;
protectedintThreshold;
protectedChain next;
publicvoidsetNext(Chain chain) {
next = chain;
}
publicvoidmessage(String msg, intpriority) {
//if the priority is less than Threshold it is handled
if(priority <= Threshold) {
writeMessage(msg);
}
if(next != null) {
next.message(msg, priority);
}
}
abstractprotectedvoidwriteMessage(String msg);
}
classA extendsChain {
publicA(intthreshold) {
this.Threshold = threshold;
}
protectedvoidwriteMessage(String msg) {
System.out.println("A: "+ msg);
}
}
classB extendsChain {
publicB(intthreshold) {
this.Threshold = threshold;
}
protectedvoidwriteMessage(String msg) {
System.out.println("B: "+ msg);
}
}
classC extendsChain {
publicC(intthreshold) {
this.Threshold = threshold;
}
protectedvoidwriteMessage(String msg) {
System.out.println("C: "+ msg);
}
}
publicclassChainOfResponsibilityExample {
privatestaticChain createChain() {
// Build the chain of responsibility
Chain chain1 = newA(Chain.Three);
Chain chain2 = newB(Chain.Two);
chain1.setNext(chain2);
Chain chain3 = newC(Chain.One);
chain2.setNext(chain3);
returnchain1;
}
publicstaticvoidmain(String[] args) {
Chain chain = createChain();
chain.message("level 3", Chain.Three);
chain.message("level 2", Chain.Two);
chain.message("level 1", Chain.One);
}
}
|
在这个例子中,1级通过了所有的单元。
A: level 3 A: level 2 B: level 2 A: level 1 B: level 1 C: level 1
这是来自维基百科的一个简单例子 - http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
命令设计模式需要一个操作和它的参数,并将其打包在一个对象并执行和记录等。在下面的例子中,Command是操作,Computer是参数,它们被包裹在Switch中。
从另一个角度看,命令模式有四部分,命令、接受器、请求者和客户端。在此示例中,Switch是请求者,Computer为接收器。一个具体Command本身指定了一个接收器对象,并会调用接收器的方法。请求者可以使用不同的具体命令。客户端决定对哪个接收器使用哪个命令。
注:老外说的有点不容易理解,下面是我自己加上的。
抽象命令(Command):定义命令的接口,声明执行的方法。
具体命令角色(ConcreteCommand): 命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
请求者(Invoker):要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
接收者(Receiver、执行者):接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
客户端(Client):创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。
命令模式类图
Java命令模式示例
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
packagedesignpatterns.command;
importjava.util.List;
importjava.util.ArrayList;
/* The Command interface */
interface Command {
void execute();
}
// in this example, suppose you use a switch to control computer
/* The Invoker class */
class Switch {
private List<Command> history = new ArrayList<Command>();
public Switch() {
}
public void storeAndExecute(Command command) {
this.history.add(command); // optional, can do the execute only!
command.execute();
}
}
/* The Receiver class */
class Computer {
public void shutDown() {
System.out.println("computer is shut down");
}
public void restart() {
System.out.println("computer is restarted");
}
}
/* The Command for shutting down the computer*/
class ShutDownCommand implements Command {
private Computer computer;
public ShutDownCommand(Computer computer) {
this.computer = computer;
}
public void execute(){
computer.shutDown();
}
}
/* The Command for restarting the computer */
class RestartCommand implements Command {
private Computer computer;
public RestartCommand(Computer computer) {
this.computer = computer;
}
public void execute() {
computer.restart();
}
}
/* The client */
publicclassTestCommand {
publicstaticvoidmain(String[] args){
Computer computer = newComputer();
Command shutdown = newShutDownCommand(computer);
Command restart = newRestartCommand(computer);
Switch s = newSwitch();
String str = "shutdown"; //get value based on real situation
if(str == "shutdown"){
s.storeAndExecute(shutdown);
}else{
s.storeAndExecute(restart);
}
}
}
|
解释器模式使用在需要解释一些背景内容的时候。下面的例子是一个很简单的解释器执行的情况。它所完成的工作是解释字母“a”和“b” 到 “1”和“2”。
类图
注:依赖关系也在图中示出,以使结构可以理解。
Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
classContext {
privateString input;
privateString output;
publicContext(String input) {
this.input = input;
this.output = "";
}
publicString getInput() {
returninput;
}
publicvoidsetInput(String input) {
this.input = input;
}
publicString getOutput() {
returnoutput;
}
publicvoidsetOutput(String output) {
this.output = output;
}
}
abstractclassExpression {
publicabstractvoidinterpret(Context context);
}
classAExpression extendsExpression {
publicvoidinterpret(Context context) {
System.out.println("a expression");
String input = context.getInput();
context.setInput(input.substring(1));
context.setOutput(context.getOutput()+ "1");
}
}
classBExpression extendsExpression {
publicvoidinterpret(Context context) {
System.out.println("b expression");
String input = context.getInput();
context.setInput(input.substring(1));
context.setOutput(context.getOutput()+ "2");
}
}
publicclassTestInterpreter {
publicstaticvoidmain(String[] args) {
String str = "ab";
Context context = newContext(str);
List<Expression> list = newArrayList<Expression>();
list.add(newAExpression());
list.add(newBExpression());
for(Expression ex : list) {
ex.interpret(context);
}
System.out.println(context.getOutput());
}
}
|
JDK中的解释器模式
java.util.Pattern
迭代器模式用来遍历对象集合。这是一个常用的设计模式,你之前可能已经用过它。当你看到的比如 hasNext() 和 next()方法时,它可能就是一个迭代器模式。例如,在你遍历数据库查询记录的列表时用到。
迭代器模式的类图
迭代器模式的Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
|
interfaceIIterator{
publicbooleanhasNext();
publicObject next();
}
interfaceIContainer{
publicIIterator createIterator();
}
classRecordCollection implementsIContainer{
privateString recordArray[] = {"first","second","third","fourth","fifth"};
publicIIterator createIterator(){
RecordIterator iterator = newRecordIterator();
returniterator;
}
privateclassRecordIterator implementsIIterator{
privateintindex;
publicbooleanhasNext(){
if(index < recordArray.length)
returntrue;
else
returnfalse;
}
publicObject next(){
if(this.hasNext())
returnrecordArray[index++];
else
returnnull;
}
}
}
publicclassTestIterator {
publicstaticvoidmain(String[] args) {
RecordCollection recordCollection = newRecordCollection();
IIterator iter = recordCollection.createIterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
}
}
|
JDK中的迭代器模式
在java.util包中,Iterator接口定义如下:
1
2
3
4
5
|
publicinterfaceIterator<E> {
booleanhasNext();
E next();
voidremove();
}
|
还有就是可以创建一个迭代器的类,如,TreeSet中的iterator(),HashSet的iterator()等。
中介者设计模式用于一组同事的协作。那些同事可以不直接与对方沟通,但通过中介。
在下面的例子中,同事A想讨论,同事B想工作。当他们想做一些协作时(doSomething()),他们援引中介来做。
中介者模式类图
中介者模式的Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
packagedesignpatterns.mediator;
interfaceIMediator {
publicvoidfight();
publicvoidtalk();
publicvoidregisterA(ColleagueA a);
publicvoidregisterB(ColleagueB a);
}
//concrete mediator
classConcreteMediator implementsIMediator{
ColleagueA talk;
ColleagueB fight;
publicvoidregisterA(ColleagueA a){
talk = a;
}
publicvoidregisterB(ColleagueB b){
fight = b;
}
publicvoidfight(){
System.out.println("Mediator is fighting");
//let the fight colleague do some stuff
}
publicvoidtalk(){
System.out.println("Mediator is talking");
//let the talk colleague do some stuff
}
}
abstractclassColleague {
IMediator mediator;
publicabstractvoiddoSomething();
}
//concrete colleague
classColleagueA extendsColleague {
publicColleagueA(IMediator mediator) {
this.mediator = mediator;
}
@Override
publicvoiddoSomething() {
this.mediator.talk();
this.mediator.registerA(this);
}
}
//concrete colleague
classColleagueB extendsColleague {
publicColleagueB(IMediator mediator) {
this.mediator = mediator;
this.mediator.registerB(this);
}
@Override
publicvoiddoSomething() {
this.mediator.fight();
}
}
publicclassMediatorTest {
publicstaticvoidmain(String[] args) {
IMediator mediator = newConcreteMediator();
ColleagueA talkColleague = newColleagueA(mediator);
ColleagueB fightColleague = newColleagueB(mediator);
talkColleague.doSomething();
fightColleague.doSomething();
}
}
|
与其他的行为模式比较,观察者模式与中介者模式最相似。您可以阅读观察者模式来比较他们的差异。
在未来,时间旅行将出现。记录是时间旅行的关键。它能做最基本的是让一个对象的回到过去的状态。
在下面的例子中,你可以时间旅行到任何你想生活的时间,并记录下来,您可以回滚到你曾经经历过的任何时间。(注,翻译的好牵强的感觉)
备忘录设计模式的类图
备忘录设计模式Java代码
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
packagedesignpatterns.memento;
importjava.util.List;
importjava.util.ArrayList;
classLife {
privateString time;
publicvoidset(String time) {
System.out.println("Setting time to "+ time);
this.time = time;
}
publicMemento saveToMemento() {
System.out.println("Saving time to Memento");
returnnewMemento(time);
}
publicvoidrestoreFromMemento(Memento memento) {
time = memento.getSavedTime();
System.out.println("Time restored from Memento: "+ time);
}
publicstaticclassMemento {
privatefinalString time;
publicMemento(String timeToSave) {
time = timeToSave;
}
publicString getSavedTime() {
returntime;
}
}
}
publicclassYou {
publicstaticvoidmain(String[] args) {
List<Life.Memento> savedTimes = newArrayList<Life.Memento>();
Life life = newLife();
//time travel and record the eras
life.set("2000 B.C.");
savedTimes.add(life.saveToMemento());
life.set("2000 A.D.");
savedTimes.add(life.saveToMemento());
life.set("3000 A.D.");
savedTimes.add(life.saveToMemento());
life.set("4000 A.D.");
life.restoreFromMemento(savedTimes.get(0));
}
}
|