Java经典设计模式(3):十一种行为型模式

本贴最后更新于 2791 天前,其中的信息可能已经时移世异

设计模式原则

Java经典设计模式共有21中,分为三大类:创建型模式(5种)、结构型模式(7种)和行为型模式(11种)。

本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之五大创建型模式(附实例和详解)、 Java经典设计模式之七大结构型模式(附实例和详解)。

行为型模式细分为如下11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

接下来对11种行为型模式逐个进行介绍。

一、策略模式

策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类,视实际需求是否添加),提供辅助函数。

首先统一接口:

package com.model.behaviour;

public interface ICalculator {
public int calculate(String exp);
}

辅助类:

package com.model.behaviour;

public abstract class AbstractCalculator {

<span class="pl-k">public</span> <span class="pl-k">int</span>[] <span class="pl-en">split</span>(<span class="pl-smi">String</span> <span class="pl-v">exp</span>, <span class="pl-smi">String</span> <span class="pl-v">opt</span>) {
    <span class="pl-smi">String</span> array[] <span class="pl-k">=</span> exp<span class="pl-k">.</span>split(opt);
    <span class="pl-k">int</span> arrayInt[] <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">int</span>[<span class="pl-c1">2</span>];
    arrayInt[<span class="pl-c1">0</span>] <span class="pl-k">=</span> <span class="pl-smi">Integer</span><span class="pl-k">.</span>parseInt(array[<span class="pl-c1">0</span>]);
    arrayInt[<span class="pl-c1">1</span>] <span class="pl-k">=</span> <span class="pl-smi">Integer</span><span class="pl-k">.</span>parseInt(array[<span class="pl-c1">1</span>]);
    <span class="pl-k">return</span> arrayInt;
}

}

三个实现类:

package com.model.behaviour;

public class Plus extends AbstractCalculator implements ICalculator {

<span class="pl-k">@Override</span>
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">calculate</span>(<span class="pl-smi">String</span> <span class="pl-v">exp</span>) {
    <span class="pl-k">int</span> arrayInt[] <span class="pl-k">=</span> split(exp, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\\</span>+<span class="pl-pds">"</span></span>);
    <span class="pl-k">return</span> arrayInt[<span class="pl-c1">0</span>] <span class="pl-k">+</span> arrayInt[<span class="pl-c1">1</span>];
}

}

package com.model.behaviour;

public class Minus extends AbstractCalculator implements ICalculator {

<span class="pl-k">@Override</span>
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">calculate</span>(<span class="pl-smi">String</span> <span class="pl-v">exp</span>) {
    <span class="pl-k">int</span> arrayInt[] <span class="pl-k">=</span> split(exp, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\\</span>-<span class="pl-pds">"</span></span>);
    <span class="pl-k">return</span> arrayInt[<span class="pl-c1">0</span>] <span class="pl-k">-</span> arrayInt[<span class="pl-c1">1</span>];
}

}

package com.model.behaviour;

public class Multiply extends AbstractCalculator implements ICalculator {

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">calculate</span>(<span class="pl-smi">String</span> <span class="pl-v">exp</span>) {  
    <span class="pl-k">int</span> arrayInt[] <span class="pl-k">=</span> split(exp,<span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\\</span>*<span class="pl-pds">"</span></span>);  
    <span class="pl-k">return</span> arrayInt[<span class="pl-c1">0</span>]<span class="pl-k">*</span>arrayInt[<span class="pl-c1">1</span>];  
}  

}

测试类:

package com.model.behaviour;

public class StrategyTest {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {
    <span class="pl-smi">String</span> exp <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>8-2<span class="pl-pds">"</span></span>;
    <span class="pl-smi">ICalculator</span> cal <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Minus</span>();
    <span class="pl-k">int</span> result <span class="pl-k">=</span> cal<span class="pl-k">.</span>calculate(exp);
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(exp <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span>=<span class="pl-pds">"</span></span> <span class="pl-k">+</span> result);
}

}

策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。

二、模板方法模式

解释一下模板方法模式,就是指:一个抽象类中,有一个主方法,再定义1…n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用。

就是在AbstractCalculator类中定义一个主方法calculate,calculate()调用spilt()等,Plus和Minus分别继承AbstractCalculator类,通过对AbstractCalculator的调用实现对子类的调用,看下面的例子:

package com.model.behaviour;

public abstract class AbstractCalculator {

<span class="pl-c">/*主方法,实现对本类其它方法的调用*/</span>  
<span class="pl-k">public</span> <span class="pl-k">final</span> <span class="pl-k">int</span> <span class="pl-en">calculate</span>(<span class="pl-smi">String</span> <span class="pl-v">exp</span>,<span class="pl-smi">String</span> <span class="pl-v">opt</span>){  
    <span class="pl-k">int</span> array[] <span class="pl-k">=</span> split(exp,opt);  
    <span class="pl-k">return</span> calculate(array[<span class="pl-c1">0</span>],array[<span class="pl-c1">1</span>]);  
}  

<span class="pl-c">/*被子类重写的方法*/</span> 
<span class="pl-k">abstract</span> <span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">calculate</span>(<span class="pl-k">int</span> <span class="pl-v">num1</span>,<span class="pl-k">int</span> <span class="pl-v">num2</span>);  

<span class="pl-k">public</span> <span class="pl-k">int</span>[] <span class="pl-en">split</span>(<span class="pl-smi">String</span> <span class="pl-v">exp</span>,<span class="pl-smi">String</span> <span class="pl-v">opt</span>){  
    <span class="pl-smi">String</span> array[] <span class="pl-k">=</span> exp<span class="pl-k">.</span>split(opt);  
    <span class="pl-k">int</span> arrayInt[] <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">int</span>[<span class="pl-c1">2</span>];  
    arrayInt[<span class="pl-c1">0</span>] <span class="pl-k">=</span> <span class="pl-smi">Integer</span><span class="pl-k">.</span>parseInt(array[<span class="pl-c1">0</span>]);  
    arrayInt[<span class="pl-c1">1</span>] <span class="pl-k">=</span> <span class="pl-smi">Integer</span><span class="pl-k">.</span>parseInt(array[<span class="pl-c1">1</span>]);  
    <span class="pl-k">return</span> arrayInt;  
}  

}

package com.model.behaviour;

public class Plus extends AbstractCalculator {

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">calculate</span>(<span class="pl-k">int</span> <span class="pl-v">num1</span>,<span class="pl-k">int</span> <span class="pl-v">num2</span>) {  
    <span class="pl-k">return</span> num1 <span class="pl-k">+</span> num2;  
}  

}

package com.model.behaviour;

public class StrategyTest {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {  
    <span class="pl-smi">String</span> exp <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>8+8<span class="pl-pds">"</span></span>;  
    <span class="pl-smi">AbstractCalculator</span> cal <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Plus</span>();  
    <span class="pl-k">int</span> result <span class="pl-k">=</span> cal<span class="pl-k">.</span>calculate(exp, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\\</span>+<span class="pl-pds">"</span></span>);  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(result);  
}  

}

三、观察者模式

包括这个模式在内的接下来的四个模式,都是类和类之间的关系,不涉及到继承。

观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。

package com.model.behaviour;

public interface Observer {
public void update();
}

``` java
package com.model.behaviour;

public class Observer1 implements Observer {

@Override 
public void update() {  
    System.out.println("observer1 has received!");  
}  

}

package com.model.behaviour;

public class Observer2 implements Observer {

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">update</span>() {  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>observer2 has received!<span class="pl-pds">"</span></span>);  
}  

}

package com.model.behaviour;

public interface Subject {

<span class="pl-c">/*增加观察者*/</span>  
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">add</span>(<span class="pl-smi">Observer</span> <span class="pl-v">observer</span>);  

<span class="pl-c">/*删除观察者*/</span>  
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">del</span>(<span class="pl-smi">Observer</span> <span class="pl-v">observer</span>);  

<span class="pl-c">/*通知所有的观察者*/</span>  
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">notifyObservers</span>();  

<span class="pl-c">/*自身的操作*/</span> 
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">operation</span>();  

}

package com.model.behaviour;

import java.util.Enumeration;
import java.util.Vector;

public abstract class AbstractSubject implements Subject {

<span class="pl-k">private</span> <span class="pl-k">Vector&lt;<span class="pl-smi">Observer</span>&gt;</span> vector <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-k">Vector&lt;<span class="pl-smi">Observer</span>&gt;</span>();  
<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">add</span>(<span class="pl-smi">Observer</span> <span class="pl-v">observer</span>) {  
    vector<span class="pl-k">.</span>add(observer);  
}  

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">del</span>(<span class="pl-smi">Observer</span> <span class="pl-v">observer</span>) {  
    vector<span class="pl-k">.</span>remove(observer);  
}  

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">notifyObservers</span>() {  
    <span class="pl-k">Enumeration&lt;<span class="pl-smi">Observer</span>&gt;</span> enumo <span class="pl-k">=</span> vector<span class="pl-k">.</span>elements();  
    <span class="pl-k">while</span>(enumo<span class="pl-k">.</span>hasMoreElements()){  
        enumo<span class="pl-k">.</span>nextElement()<span class="pl-k">.</span>update();  
    }  
}  

}

package com.model.behaviour;

public class MySubject extends AbstractSubject {

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">operation</span>() {  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>update self!<span class="pl-pds">"</span></span>);  
    notifyObservers();  
}  

}

package com.model.behaviour;

public class ObserverTest {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {  
    <span class="pl-smi">Subject</span> sub <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">MySubject</span>();  
    sub<span class="pl-k">.</span>add(<span class="pl-k">new</span> <span class="pl-smi">Observer1</span>());  
    sub<span class="pl-k">.</span>add(<span class="pl-k">new</span> <span class="pl-smi">Observer2</span>());  

    sub<span class="pl-k">.</span>operation();  
}  

}

运行结果:

update self!
observer1 has received!
observer2 has received!

也许看完实例之后还是比较抽象,再将文字描述和代码实例看一两遍吧,然后结合工作中看哪些场景可以使用这种模式以加深理解。

四、迭代子模式

顾名思义,迭代器模式就是顺序访问聚集中的对象,一般来说,集合中非常常见,如果对集合类比较熟悉的话,理解本模式会十分轻松。这句话包含两层意思:一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问。

具体来看看代码实例:

package com.model.behaviour;

public interface Collection {

<span class="pl-k">public</span> <span class="pl-smi">Iterator</span> <span class="pl-en">iterator</span>();

<span class="pl-c">/* 取得集合元素 */</span>
<span class="pl-k">public</span> <span class="pl-smi">Object</span> <span class="pl-en">get</span>(<span class="pl-k">int</span> <span class="pl-v">i</span>);

<span class="pl-c">/* 取得集合大小 */</span>
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">size</span>();

}

package com.model.behaviour;

public interface Iterator {
// 前移
public Object previous();

<span class="pl-c">// 后移</span>
<span class="pl-k">public</span> <span class="pl-smi">Object</span> <span class="pl-en">next</span>();

<span class="pl-k">public</span> <span class="pl-k">boolean</span> <span class="pl-en">hasNext</span>();

<span class="pl-c">// 取得第一个元素</span>
<span class="pl-k">public</span> <span class="pl-smi">Object</span> <span class="pl-en">first</span>();

}

package com.model.behaviour;

public class MyCollection implements Collection {

<span class="pl-k">public</span> <span class="pl-smi">String</span> string[] <span class="pl-k">=</span> { <span class="pl-s"><span class="pl-pds">"</span>A<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>B<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>D<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>E<span class="pl-pds">"</span></span> };

<span class="pl-k">@Override</span>
<span class="pl-k">public</span> <span class="pl-smi">Iterator</span> <span class="pl-en">iterator</span>() {
    <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">MyIterator</span>(<span class="pl-v">this</span>);
}

<span class="pl-k">@Override</span>
<span class="pl-k">public</span> <span class="pl-smi">Object</span> <span class="pl-en">get</span>(<span class="pl-k">int</span> <span class="pl-v">i</span>) {
    <span class="pl-k">return</span> string[i];
}

<span class="pl-k">@Override</span>
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">size</span>() {
    <span class="pl-k">return</span> string<span class="pl-k">.</span>length;
}

}

package com.model.behaviour;

public class MyIterator implements Iterator {

<span class="pl-k">private</span> <span class="pl-smi">Collection</span> collection;  
<span class="pl-k">private</span> <span class="pl-k">int</span> pos <span class="pl-k">=</span> <span class="pl-k">-</span><span class="pl-c1">1</span>;  

<span class="pl-k">public</span> <span class="pl-en">MyIterator</span>(<span class="pl-smi">Collection</span> <span class="pl-v">collection</span>){  
    <span class="pl-v">this</span><span class="pl-k">.</span>collection <span class="pl-k">=</span> collection;  
}  

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-smi">Object</span> <span class="pl-en">previous</span>() {  
    <span class="pl-k">if</span>(pos <span class="pl-k">&gt;</span> <span class="pl-c1">0</span>){  
        pos<span class="pl-k">--</span>;  
    }  
    <span class="pl-k">return</span> collection<span class="pl-k">.</span>get(pos);  
}  

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-smi">Object</span> <span class="pl-en">next</span>() {  
    <span class="pl-k">if</span>(pos<span class="pl-k">&lt;</span>collection<span class="pl-k">.</span>size()<span class="pl-k">-</span><span class="pl-c1">1</span>){  
        pos<span class="pl-k">++</span>;  
    }  
    <span class="pl-k">return</span> collection<span class="pl-k">.</span>get(pos);  
}  

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">boolean</span> <span class="pl-en">hasNext</span>() {  
    <span class="pl-k">if</span>(pos<span class="pl-k">&lt;</span>collection<span class="pl-k">.</span>size()<span class="pl-k">-</span><span class="pl-c1">1</span>){  
        <span class="pl-k">return</span> <span class="pl-c1">true</span>;  
    }<span class="pl-k">else</span>{  
        <span class="pl-k">return</span> <span class="pl-c1">false</span>;  
    }  
}  

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-smi">Object</span> <span class="pl-en">first</span>() {  
    pos <span class="pl-k">=</span> <span class="pl-c1">0</span>;  
    <span class="pl-k">return</span> collection<span class="pl-k">.</span>get(pos);  
}  

}

package com.model.behaviour;

public class Test {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {  
    <span class="pl-smi">Collection</span> collection <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">MyCollection</span>();  
    <span class="pl-smi">Iterator</span> it <span class="pl-k">=</span> (<span class="pl-smi">Iterator</span>) collection<span class="pl-k">.</span>iterator();  
    <span class="pl-k">while</span>(it<span class="pl-k">.</span>hasNext()){  
        <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(it<span class="pl-k">.</span>next());  
    }  
}  

}

输出结果:

A
B
C
D
E

此处我们貌似模拟了一个集合类的过程,感觉是不是很爽?其实JDK中各个类也都是这些基本的东西,加一些设计模式,再加一些优化放到一起的,只要我们把这些东西学会了,掌握好了,我们也可以写出自己的集合类,甚至框架!

五、责任链模式

责任链模式,有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。

package com.model.behaviour;

public interface Handler {
public void operator();
}

package com.model.behaviour;

public abstract class AbstractHandler {

<span class="pl-k">private</span> <span class="pl-smi">Handler</span> handler;

<span class="pl-k">public</span> <span class="pl-smi">Handler</span> <span class="pl-en">getHandler</span>() {
    <span class="pl-k">return</span> handler;
}

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setHandler</span>(<span class="pl-smi">Handler</span> <span class="pl-v">handler</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>handler <span class="pl-k">=</span> handler;
}

}

package com.model.behaviour;

public class MyHandler extends AbstractHandler implements Handler {

<span class="pl-k">private</span> <span class="pl-smi">String</span> name;

<span class="pl-k">public</span> <span class="pl-en">MyHandler</span>(<span class="pl-smi">String</span> <span class="pl-v">name</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>name <span class="pl-k">=</span> name;
}

<span class="pl-k">@Override</span>
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">operator</span>() {
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(name <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span>deal!<span class="pl-pds">"</span></span>);
    <span class="pl-k">if</span> (getHandler() <span class="pl-k">!=</span> <span class="pl-c1">null</span>) {
        getHandler()<span class="pl-k">.</span>operator();
    }
}

}

package com.model.behaviour;

public class Test {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {
    <span class="pl-smi">MyHandler</span> h1 <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">MyHandler</span>(<span class="pl-s"><span class="pl-pds">"</span>h1<span class="pl-pds">"</span></span>);
    <span class="pl-smi">MyHandler</span> h2 <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">MyHandler</span>(<span class="pl-s"><span class="pl-pds">"</span>h2<span class="pl-pds">"</span></span>);
    <span class="pl-smi">MyHandler</span> h3 <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">MyHandler</span>(<span class="pl-s"><span class="pl-pds">"</span>h3<span class="pl-pds">"</span></span>);

    h1<span class="pl-k">.</span>setHandler(h2);
    h2<span class="pl-k">.</span>setHandler(h3);

    h1<span class="pl-k">.</span>operator();
}

}

运行结果:

h1deal!
h2deal!
h3deal!

此处强调一点就是,链接上的请求可以是一条链,可以是一个树,还可以是一个环,模式本身不约束这个,需要我们自己去实现,同时,在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。

六、命令模式

命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其他人,只需要做好自己的事儿就行,司令员要的是结果,不会去关注到底士兵是怎么实现的。

package com.model.behaviour;

public interface Command {
public void exe();
}

package com.model.behaviour;

public class MyCommand implements Command {

<span class="pl-k">private</span> <span class="pl-smi">Receiver</span> receiver;  

<span class="pl-k">public</span> <span class="pl-en">MyCommand</span>(<span class="pl-smi">Receiver</span> <span class="pl-v">receiver</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>receiver <span class="pl-k">=</span> receiver;  
}  

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">exe</span>() {  
    receiver<span class="pl-k">.</span>action();  
}  

}

package com.model.behaviour;

public class Invoker {

<span class="pl-k">private</span> <span class="pl-smi">Command</span> command;

<span class="pl-k">public</span> <span class="pl-en">Invoker</span>(<span class="pl-smi">Command</span> <span class="pl-v">command</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>command <span class="pl-k">=</span> command;
}

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">action</span>() {
    command<span class="pl-k">.</span>exe();
}

}

package com.model.behaviour;

public class Test {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {  
    <span class="pl-smi">Receiver</span> receiver <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Receiver</span>();  
    <span class="pl-smi">Command</span> cmd <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">MyCommand</span>(receiver);  
    <span class="pl-smi">Invoker</span> invoker <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Invoker</span>(cmd);  
    invoker<span class="pl-k">.</span>action();  
}  

}

命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开,熟悉Struts的同学应该知道,Struts其实就是一种将请求和呈现分离的技术,其中必然涉及命令模式的思想!

七、备忘录模式

主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B是用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。

package com.model.behaviour;

public class Original {

<span class="pl-k">private</span> <span class="pl-smi">String</span> value;  

<span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getValue</span>() {  
    <span class="pl-k">return</span> value;  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setValue</span>(<span class="pl-smi">String</span> <span class="pl-v">value</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>value <span class="pl-k">=</span> value;  
}  

<span class="pl-k">public</span> <span class="pl-en">Original</span>(<span class="pl-smi">String</span> <span class="pl-v">value</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>value <span class="pl-k">=</span> value;  
}  

<span class="pl-k">public</span> <span class="pl-smi">Memento</span> <span class="pl-en">createMemento</span>(){  
    <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">Memento</span>(value);  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">restoreMemento</span>(<span class="pl-smi">Memento</span> <span class="pl-v">memento</span>){  
    <span class="pl-v">this</span><span class="pl-k">.</span>value <span class="pl-k">=</span> memento<span class="pl-k">.</span>getValue();  
}  

}

package com.model.behaviour;

public class Memento {

<span class="pl-k">private</span> <span class="pl-smi">String</span> value;

<span class="pl-k">public</span> <span class="pl-en">Memento</span>(<span class="pl-smi">String</span> <span class="pl-v">value</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>value <span class="pl-k">=</span> value;
}

<span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getValue</span>() {
    <span class="pl-k">return</span> value;
}

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setValue</span>(<span class="pl-smi">String</span> <span class="pl-v">value</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>value <span class="pl-k">=</span> value;
}

}

package com.model.behaviour;

public class Storage {

<span class="pl-k">private</span> <span class="pl-smi">Memento</span> memento;  

<span class="pl-k">public</span> <span class="pl-en">Storage</span>(<span class="pl-smi">Memento</span> <span class="pl-v">memento</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>memento <span class="pl-k">=</span> memento;  
}  

<span class="pl-k">public</span> <span class="pl-smi">Memento</span> <span class="pl-en">getMemento</span>() {  
    <span class="pl-k">return</span> memento;  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setMemento</span>(<span class="pl-smi">Memento</span> <span class="pl-v">memento</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>memento <span class="pl-k">=</span> memento;  
}  

}

package com.model.behaviour;

public class Test {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {

    <span class="pl-c">// 创建原始类</span>
    <span class="pl-smi">Original</span> origi <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Original</span>(<span class="pl-s"><span class="pl-pds">"</span>egg<span class="pl-pds">"</span></span>);

    <span class="pl-c">// 创建备忘录</span>
    <span class="pl-smi">Storage</span> storage <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Storage</span>(origi<span class="pl-k">.</span>createMemento());

    <span class="pl-c">// 修改原始类的状态</span>
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>初始化状态为:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> origi<span class="pl-k">.</span>getValue());
    origi<span class="pl-k">.</span>setValue(<span class="pl-s"><span class="pl-pds">"</span>niu<span class="pl-pds">"</span></span>);
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>修改后的状态为:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> origi<span class="pl-k">.</span>getValue());

    <span class="pl-c">// 回复原始类的状态</span>
    origi<span class="pl-k">.</span>restoreMemento(storage<span class="pl-k">.</span>getMemento());
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>恢复后的状态为:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> origi<span class="pl-k">.</span>getValue());
}

}

输出结果:

初始化状态为:egg
修改后的状态为:niu
恢复后的状态为:egg
如果还不能理解,可以给Original类添加一个属性name,然后其他类进行相应的修改试试。

八、状态模式

核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿QQ来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:1、可以通过改变状态来获得不同的行为。2、你的好友能同时看到你的变化。

package com.model.behaviour;

public class State {

<span class="pl-k">private</span> <span class="pl-smi">String</span> value;  

<span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getValue</span>() {  
    <span class="pl-k">return</span> value;  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setValue</span>(<span class="pl-smi">String</span> <span class="pl-v">value</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>value <span class="pl-k">=</span> value;  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">method1</span>(){  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>execute the first opt!<span class="pl-pds">"</span></span>);  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">method2</span>(){  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>execute the second opt!<span class="pl-pds">"</span></span>);  
}  

}

package com.model.behaviour;

public class Context {

<span class="pl-k">private</span> <span class="pl-smi">State</span> state;

<span class="pl-k">public</span> <span class="pl-en">Context</span>(<span class="pl-smi">State</span> <span class="pl-v">state</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>state <span class="pl-k">=</span> state;
}

<span class="pl-k">public</span> <span class="pl-smi">State</span> <span class="pl-en">getState</span>() {
    <span class="pl-k">return</span> state;
}

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setState</span>(<span class="pl-smi">State</span> <span class="pl-v">state</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>state <span class="pl-k">=</span> state;
}

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">method</span>() {
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>状态为:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> state<span class="pl-k">.</span>getValue());
    <span class="pl-k">if</span> (state<span class="pl-k">.</span>getValue()<span class="pl-k">.</span>equals(<span class="pl-s"><span class="pl-pds">"</span>state1<span class="pl-pds">"</span></span>)) {
        state<span class="pl-k">.</span>method1();
    } <span class="pl-k">else</span> <span class="pl-k">if</span> (state<span class="pl-k">.</span>getValue()<span class="pl-k">.</span>equals(<span class="pl-s"><span class="pl-pds">"</span>state2<span class="pl-pds">"</span></span>)) {
        state<span class="pl-k">.</span>method2();
    }
}

}

package com.model.behaviour;

public class Test {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {  

    <span class="pl-smi">State</span> state <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">State</span>();  
    <span class="pl-smi">Context</span> context <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Context</span>(state);  

    <span class="pl-c">//设置第一种状态  </span>
    state<span class="pl-k">.</span>setValue(<span class="pl-s"><span class="pl-pds">"</span>state1<span class="pl-pds">"</span></span>);  
    context<span class="pl-k">.</span>method();  

    <span class="pl-c">//设置第二种状态  </span>
    state<span class="pl-k">.</span>setValue(<span class="pl-s"><span class="pl-pds">"</span>state2<span class="pl-pds">"</span></span>);  
    context<span class="pl-k">.</span>method();  
}  

}

运行结果:

状态为:state1
execute the first opt!
状态为:state2
execute the second opt!

根据这个特性,状态模式在日常开发中用的挺多的,尤其是做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。

九、访问者模式

访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。

访问者模式算是最复杂也是最难以理解的一种模式了。它表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

涉及角色:

1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。

2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口。

3.Element 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。

4.ConcreteElement 具体元素,实现了抽象元素(Element)所定义的接受操作接口。

5.ObjectStructure 结构对象角色,这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

abstract class Element
{
    public abstract void accept(IVisitor visitor);
    public abstract void doSomething();
}
class ConcreteElement1 extends Element{
    public void doSomething(){
        System.out.println("这是元素1");
    }
    public void accept(IVisitor visitor){
        visitor.visit(this);
    }
}
class ConcreteElement2 extends Element{
    public void doSomething(){
        System.out.println("这是元素2");
    }
    public void accept(IVisitor visitor){
        visitor.visit(this);
    }
}
interface IVisitor{
    public void visit(ConcreteElement1 el1);
    public void visit(ConcreteElement2 el2);
}
class Visitor implements IVisitor{
    public void visit(ConcreteElement1 el1){
        el1.doSomething();
    }
    public void visit(ConcreteElement2 el2){
        el2.doSomething();
    }
}
class ObjectStruture{
    public static List<Element> getList(){
        List<Element>list = new ArrayList<Element>();
        Random ran = newRandom();
        for(int i = 0 ; i < 10 ; i ++){
            int a=ran.nextInt(100);
            if(a>50){
                list.add(new ConcreteElement1());
            }else{
                list.add(new ConcreteElement2());
            }
        }
        return list;
    }
}
public class Client{
    public static void main (String[]args){
        List<Element> list = ObjectStruture.getList();
        for(Element e:list){
            e.accept(new Visitor());
        }
    }
}

十、中介者模式

中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

举例:在一个公司里面,有很多部门、员工(我们统称他们互相为Colleague“同事”),为了完成一定的任务,“同事”之间肯定有许多需要互相配合、交流的过程。如果由各个“同事”频繁地到处去与自己有关的“同事”沟通,这样肯定会形成一个多对多的杂乱的联系网络而造成工作效率低下。

此时就需要一位专门的“中介者”给各个“同事”分配任务,以及统一跟进大家的进度并在“同事”之间实时地进行交互,保证“同事”之间必须的沟通交流。很明显我们知道此时的“中介者”担任了沟通“同事”彼此之间的重要角色了,“中介者”使得每个“同事”都变成一对一的联系方式,减轻了每个“同事”的负担,增强工作效率。

同事类族:

package com.model.behaviour;

public abstract class AbstractColleague {
protected AbstractMediator mediator;

<span class="pl-c">/**既然有中介者,那么每个具体同事必然要与中介者有联系,  </span>

* 否则就没必要存在于 这个系统当中,这里的构造函数相当
* 于向该系统中注册一个中介者,以取得联系
*/
public AbstractColleague(AbstractMediator mediator) {
this.mediator = mediator;
}

<span class="pl-c">// 在抽象同事类中添加用于与中介者取得联系(即注册)的方法  </span>
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setMediator</span>(<span class="pl-smi">AbstractMediator</span> <span class="pl-v">mediator</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>mediator <span class="pl-k">=</span> mediator;  
}  

}

//具体同事A  
package com.model.behaviour;

public class ColleagueA extends AbstractColleague {

<span class="pl-c">//每个具体同事都通过父类构造函数与中介者取得联系  </span>
<span class="pl-k">public</span> <span class="pl-en">ColleagueA</span>(<span class="pl-smi">AbstractMediator</span> <span class="pl-v">mediator</span>) {  
    <span class="pl-v">super</span>(mediator);  
}  

<span class="pl-c">//每个具体同事必然有自己分内的事,没必要与外界相关联  </span>
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">self</span>() {  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>同事A --&gt; 做好自己分内的事情 ...<span class="pl-pds">"</span></span>);  
}  

<span class="pl-c">//每个具体同事总有需要与外界交互的操作,通过中介者来处理这些逻辑并安排工作  </span>
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">out</span>() {  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>同事A --&gt; 请求同事B做好分内工作 ...<span class="pl-pds">"</span></span>);  
    <span class="pl-v">super</span><span class="pl-k">.</span>mediator<span class="pl-k">.</span>execute(<span class="pl-s"><span class="pl-pds">"</span>ColleagueB<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>self<span class="pl-pds">"</span></span>);  
}  

}

//具体同事B  
package com.model.behaviour;

public class ColleagueB extends AbstractColleague {

<span class="pl-k">public</span> <span class="pl-en">ColleagueB</span>(<span class="pl-smi">AbstractMediator</span> <span class="pl-v">mediator</span>) {  
    <span class="pl-v">super</span>(mediator);  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">self</span>() {  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>同事B --&gt; 做好自己分内的事情 ...<span class="pl-pds">"</span></span>);  
}  

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">out</span>() {  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>同事B --&gt; 请求同事A做好分内工作  ...<span class="pl-pds">"</span></span>);  
    <span class="pl-v">super</span><span class="pl-k">.</span>mediator<span class="pl-k">.</span>execute(<span class="pl-s"><span class="pl-pds">"</span>ColleagueA<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>self<span class="pl-pds">"</span></span>);  
}  

}

中介者类族:

package com.model.behaviour;

public abstract class AbstractMediator {

<span class="pl-c">//中介者肯定需要保持有若干同事的联系方式  </span>
<span class="pl-k">protected</span> <span class="pl-k">Hashtable&lt;<span class="pl-smi">String</span>, <span class="pl-smi">AbstractColleague</span>&gt;</span> colleagues <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-k">Hashtable&lt;<span class="pl-smi">String</span>, <span class="pl-smi">AbstractColleague</span>&gt;</span>();  

<span class="pl-c">//中介者可以动态地与某个同事建立联系  </span>
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">addColleague</span>(<span class="pl-smi">String</span> <span class="pl-v">name</span>, <span class="pl-smi">AbstractColleague</span> <span class="pl-v">c</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>colleagues<span class="pl-k">.</span>put(name, c);  
}     

<span class="pl-c">//中介者也可以动态地撤销与某个同事的联系  </span>
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">deleteColleague</span>(<span class="pl-smi">String</span> <span class="pl-v">name</span>) {  
    <span class="pl-v">this</span><span class="pl-k">.</span>colleagues<span class="pl-k">.</span>remove(name);  
}  

<span class="pl-c">//中介者必须具备在同事之间处理逻辑、分配任务、促进交流的操作  </span>
<span class="pl-k">public</span> <span class="pl-k">abstract</span> <span class="pl-k">void</span> <span class="pl-en">execute</span>(<span class="pl-smi">String</span> <span class="pl-v">name</span>, <span class="pl-smi">String</span> <span class="pl-v">method</span>);   

}

//具体中介者  
package com.model.behaviour;

public class Mediator extends AbstractMediator{

<span class="pl-c">//中介者最重要的功能,来回奔波与各个同事之间  </span>
<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">execute</span>(<span class="pl-smi">String</span> <span class="pl-v">name</span>, <span class="pl-smi">String</span> <span class="pl-v">method</span>) {  

    <span class="pl-k">if</span>(<span class="pl-s"><span class="pl-pds">"</span>self<span class="pl-pds">"</span></span><span class="pl-k">.</span>equals(method)){  <span class="pl-c">//各自做好分内事  </span>
        <span class="pl-k">if</span>(<span class="pl-s"><span class="pl-pds">"</span>ColleagueA<span class="pl-pds">"</span></span><span class="pl-k">.</span>equals(name)) {  
            <span class="pl-smi">ColleagueA</span> colleague <span class="pl-k">=</span> (<span class="pl-smi">ColleagueA</span>)<span class="pl-v">super</span><span class="pl-k">.</span>colleagues<span class="pl-k">.</span>get(<span class="pl-s"><span class="pl-pds">"</span>ColleagueA<span class="pl-pds">"</span></span>);  
            colleague<span class="pl-k">.</span>self();  
        }<span class="pl-k">else</span> {  
            <span class="pl-smi">ColleagueB</span> colleague <span class="pl-k">=</span> (<span class="pl-smi">ColleagueB</span>)<span class="pl-v">super</span><span class="pl-k">.</span>colleagues<span class="pl-k">.</span>get(<span class="pl-s"><span class="pl-pds">"</span>ColleagueB<span class="pl-pds">"</span></span>);  
            colleague<span class="pl-k">.</span>self();  
        }  
    }<span class="pl-k">else</span> { <span class="pl-c">//与其他同事合作  </span>
        <span class="pl-k">if</span>(<span class="pl-s"><span class="pl-pds">"</span>ColleagueA<span class="pl-pds">"</span></span><span class="pl-k">.</span>equals(name)) {  
            <span class="pl-smi">ColleagueA</span> colleague <span class="pl-k">=</span> (<span class="pl-smi">ColleagueA</span>)<span class="pl-v">super</span><span class="pl-k">.</span>colleagues<span class="pl-k">.</span>get(<span class="pl-s"><span class="pl-pds">"</span>ColleagueA<span class="pl-pds">"</span></span>);  
            colleague<span class="pl-k">.</span>out();  
        }<span class="pl-k">else</span> {  
            <span class="pl-smi">ColleagueB</span> colleague <span class="pl-k">=</span> (<span class="pl-smi">ColleagueB</span>)<span class="pl-v">super</span><span class="pl-k">.</span>colleagues<span class="pl-k">.</span>get(<span class="pl-s"><span class="pl-pds">"</span>ColleagueB<span class="pl-pds">"</span></span>);  
            colleague<span class="pl-k">.</span>out();  
        }  
    }  
}  

}

测试类:

//测试类  
package com.model.behaviour;

public class Client {
public static void main(String[] args) {

    <span class="pl-c">//创建一个中介者  </span>
    <span class="pl-smi">AbstractMediator</span> mediator <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Mediator</span>();  

    <span class="pl-c">//创建两个同事  </span>
    <span class="pl-smi">ColleagueA</span> colleagueA <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">ColleagueA</span>(mediator);  
    <span class="pl-smi">ColleagueB</span> colleagueB <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">ColleagueB</span>(mediator);  

    <span class="pl-c">//中介者分别与每个同事建立联系  </span>
    mediator<span class="pl-k">.</span>addColleague(<span class="pl-s"><span class="pl-pds">"</span>ColleagueA<span class="pl-pds">"</span></span>, colleagueA);  
    mediator<span class="pl-k">.</span>addColleague(<span class="pl-s"><span class="pl-pds">"</span>ColleagueB<span class="pl-pds">"</span></span>, colleagueB);  

    <span class="pl-c">//同事们开始工作  </span>
    colleagueA<span class="pl-k">.</span>self();  
    colleagueA<span class="pl-k">.</span>out();  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>======================合作愉快,任务完成!<span class="pl-cce">\n</span><span class="pl-pds">"</span></span>);  

    colleagueB<span class="pl-k">.</span>self();  
    colleagueB<span class="pl-k">.</span>out();  
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>======================合作愉快,任务完成!<span class="pl-pds">"</span></span>);  
}  

}

运行结果:

同事A --> 做好自己分内的事情 ...  
同事A --> 请求同事B做好分内工作 ...  
同事B --> 做好自己分内的事情 ...  
======================合作愉快,任务完成!

同事B --> 做好自己分内的事情 ...
同事B --> 请求同事A做好分内工作 ...
同事A --> 做好自己分内的事情 ...
======================合作愉快,任务完成!

十一、解释器模式

解释器模式:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子。

解释器模式是一个比较少用的模式。

package com.model.behaviour;

public class Context {

<span class="pl-k">private</span> <span class="pl-k">int</span> num1;
<span class="pl-k">private</span> <span class="pl-k">int</span> num2;

<span class="pl-k">public</span> <span class="pl-en">Context</span>(<span class="pl-k">int</span> <span class="pl-v">num1</span>, <span class="pl-k">int</span> <span class="pl-v">num2</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>num1 <span class="pl-k">=</span> num1;
    <span class="pl-v">this</span><span class="pl-k">.</span>num2 <span class="pl-k">=</span> num2;
}

<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">getNum1</span>() {
    <span class="pl-k">return</span> num1;
}

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setNum1</span>(<span class="pl-k">int</span> <span class="pl-v">num1</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>num1 <span class="pl-k">=</span> num1;
}

<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">getNum2</span>() {
    <span class="pl-k">return</span> num2;
}

<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">setNum2</span>(<span class="pl-k">int</span> <span class="pl-v">num2</span>) {
    <span class="pl-v">this</span><span class="pl-k">.</span>num2 <span class="pl-k">=</span> num2;
}

}

package com.model.behaviour;

public interface Expression {
public int interpret(Context context);
}

package com.model.behaviour;

public class Minus implements Expression {

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">interpret</span>(<span class="pl-smi">Context</span> <span class="pl-v">context</span>) {  
    <span class="pl-k">return</span> context<span class="pl-k">.</span>getNum1()<span class="pl-k">-</span>context<span class="pl-k">.</span>getNum2();  
}  

}

package com.model.behaviour;

public class Plus implements Expression {

<span class="pl-k">@Override</span> 
<span class="pl-k">public</span> <span class="pl-k">int</span> <span class="pl-en">interpret</span>(<span class="pl-smi">Context</span> <span class="pl-v">context</span>) {  
    <span class="pl-k">return</span> context<span class="pl-k">.</span>getNum1()<span class="pl-k">+</span>context<span class="pl-k">.</span>getNum2();  
}  

}

package com.model.behaviour;

public class Test {

<span class="pl-k">public</span> <span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">main</span>(<span class="pl-k">String</span>[] <span class="pl-v">args</span>) {
    <span class="pl-c">// 计算9+2-8的值</span>
    <span class="pl-k">int</span> result <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Minus</span>()<span class="pl-k">.</span>interpret((<span class="pl-k">new</span> <span class="pl-smi">Context</span>(<span class="pl-k">new</span> <span class="pl-smi">Plus</span>()
            .interpret(<span class="pl-k">new</span> <span class="pl-smi">Context</span>(<span class="pl-c1">9</span>, <span class="pl-c1">2</span>)), <span class="pl-c1">8</span>)));
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(result);
}

}

原文:http://blog.csdn.net/u013142781/article/details/50825301

  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    198 引用 • 120 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...