0%

Java设计模式-行为型模式

一、概述

二、模板方法模式

模板方法角色:

  • 抽象类:负责给出一个算法的轮廓和骨架,它由一个模板方法的若干个基本方法构成
  • 具体子类:实现抽象类中所定义的抽象方法和钩子方法

抽象类中的方法有以下几类:

  • 模板方法:定义算法的股价,按照某种顺序调用其包含的基本方法
  • 基本方法:整个算法中的一个步骤,由具体子类实现
    • 抽象方法:在抽象类中声明,由具体子类实现
    • 具体方法:在抽象类中已经实现,在具体子类中可以继承或重写
    • 钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种

2.1 实现

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
public class Clent{
public static void main(String[] args){
AbstractClass tm = new ConcreteClass();
tm.templateMethod();
}
}

abstract class AbstractClass{
public void templateMethod(){
specificMethod();
abstractMehtod1();
abstractMehtod2();
}

public void specificMethod(){
System.out.println("抽象类中的具体方法被调用...");
}

public abstract void abstractMethod1();
public abstract void abstractMethod2();
}

class ConcreteClass extends AbstractClass{
public void abstractMethod1(){
System.out.println("抽象方法1的实现被调用...");
}

public void abstractMethod1(){
System.out.println("抽象方法2的实现被调用...");
}
}

/*
抽象类中的具体方法被调用...
抽象方法1的实现被调用...
抽象方法1的实现被调用...
*/

2.2 应用

三、策略模式

该模式定义了一系列算法并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

策略模式的主要角色:

抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现

具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。

环境(Context)类:持有一个策略类的引用,最终给客户端调用

3.1 实现

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
// 访问类
public class StrategyPattern {
public static void main(String[] args) {
Context c = new Context();
Strategy s = new ConcreteStrategyA();
c.setStrategy(s);
c.strategyMethod();
System.out.println("------------------------");
s = new ConcreteStrategyB();
c.setStrategy(s);
c.strategyMethod();
}
}

interface Strategy{
public void strategyMethod();
}

// 具体策略A
class ConcreteStrategyA implements Strategy{
public void strategyMethod() {
System.out.println("具体策略A的策略方法被访问!");
}
}

// 具体策略B
class ConcreteStrategyB implements Strategy{
public void strategyMethod() {
System.out.println("具体策略B的策略方法被访问!");
}
}

// 环境类
class Context{
private Strategy strategy;

public Strategy getStrategy() {
return strategy;
}

public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}

public void strategyMethod(){
strategy.strategyMethod();
}
}

3.2 应用

四、命令模式

命令( ommand )模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

命令模式的主要角色:

  • 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法execute()
  • 具体命令角色(Concrete Command)角色:是抽象命令的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令执行的操作
  • 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者
  • 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者

4.1 实现

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
public class CommandPattern {
public static void main(String[] args) {
Command cmd = new ConcreteCommand();
Invoker ir = new Invoker(cmd);
System.out.println("客户访问调用者的call()方法...");
ir.call();
}
}

class Invoker{
private Command command;

public Invoker(Command command){
this.command = command;
}

public void setCommand(Command command){
this.command = command;
}

public void call(){
System.out.println("调用者执行命令command...");
command.execute();
}
}

interface Command{
public abstract void execute();
}

class ConcreteCommand implements Command{
private Receiver receiver;

ConcreteCommand(){
receiver = new Receiver();
}

public void execute(){
receiver.action();
}
}

class Receiver{
public void action(){
System.out.println("接收者的action()方法被调用...");
}
}
/*
客户访问调用者的call()方法...
调用者执行命令command...
接收者的action()方法被调用...
*/

4.2 应用

五、职责链模式

为了避免请求发送者与多个请求处理者糯合在 起,将所有请求的处理者通过前一对象记住其下个对象的引用而连成一条链当有求发生时,可将请求沿着这条链传递,直到有对象处理它为止

职责链的主要角色:

  • 抽象处理者角色(Handler):定义一个处理请求的接口,包含抽象处理方法和一个后继连接
  • 具体处理者角色(ConcreteHandler):实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者
  • 客户类角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程

5.1 实现

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
public class ChainOfResponsibilityPattern {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
handler1.setNext(handler2);
handler1.handleRequest("two");
}
}

// 抽象处理者角色
abstract class Handler{
private Handler next;

public Handler getNext() {
return next;
}

public void setNext(Handler next) {
this.next = next;
}

public abstract void handleRequest(String request);
}

class ConcreteHandler1 extends Handler{
@Override
public void handleRequest(String request) {
if (request.equals("one")){
System.out.println("具体处理1负责处理该请求!");
} else{
if (getNext() != null){
getNext().handleRequest(request);
}else {
System.out.println("没有人处理该请求!");
}
}
}
}

class ConcreteHandler2 extends Handler{
@Override
public void handleRequest(String request) {
if (request.equals("two")){
System.out.println("具体处理2负责处理该请求!");
} else{
if (getNext() != null){
getNext().handleRequest(request);
}else {
System.out.println("没有人处理该请求!");
}
}
}
}

5.2 应用

六、状态模式

状态模式:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中, 允许状态对象在其内部状态发生改变时改变其行为。

状态模式的主要角色:

  • 环境角色(Context):也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理
  • 抽象状态角色(State):定义一个接口,用以封装环境对象中的特定状态所对应的行为
  • 具体状态角色(Concrete State):实现抽象状态所对应的行为

6.1 实现

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
public class StatePatternClient {
public static void main(String[] args) {
Context context = new Context(); // 创建环境
context.Handle(); // 处理请求
context.Handle();
context.Handle();
context.Handle();
}
}

// 环境类
class Context{
private State state;

public Context(){
this.state = ConcreteStateA();
}

public Handler getState() {
return state;
}

public void setState(State state) {
this.state = state;
}

public void Handle(){
state.Handle(this);
}
}

// 抽象状态类
abstract class State{
public abstract void Handle(Context context);
}

// 具体状态类A
class ConcreteStateA extends State{
public void Handle(Context context){
System.out.println("当前状态是A.")
context.setState(new ConcreteStateB());
}
}

// 具体状态类B
class ConcreteStateA extends State{
public void Handle(Context context){
System.out.println("当前状态是B.")
context.setState(new ConcreteStateA());
}
}

/*
当前状态是A.
当前状态是B.
当前状态是A.
当前状态是B.
*/

6.2 应用

七、观察者模式

观察者模式:指多个对象存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式 它是对象行为型模式。

观察者模式的主要角色:

  • 抽象主题Subject:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法
  • 具体主题Concrete Subject:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象
  • 抽象观察者Observer:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用
  • 具体观察者Concrete Observer:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态

7.1 实现

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
public class ObserverPattern{
public static void main(String[] args){
Subject subject = new ConcreteSubject();
Observer obs1 = new ConcreteObserver1();
Observer obs2 = new ConcreteObserver2();
subject.add(obs1);
subject.add(obs2);
subject.notifyObserver();
}
}

abstract class Subject{
protected List<Object> observers = new ArrayList<Observer>();
// 添加观察者
public void add(Observer observer){
observers.add(observer);
}

// 删除观察者
public void remove(Observer observer){
observers.remove(observer);
}

public abstract void notifyObserver(); // 通知观察者方法
}

class ConcreteSubject extends Subject{
public void notifyObserver(){
System.out.println("具体目标发生改变...");
System.out.println("----------------");

for(Object obs:observers){
((Observer)obs).response();
}
}
}

interface Observer{
void response();
}

class ConcreteObserver1 implement Observer{
public void response(){
System.out.println("具体观察者1做出反应...");
}
}

class ConcreteObserver2 implement Observer{
public void response(){
System.out.println("具体观察者2做出反应...");
}
}

/*
具体目标发生改变...
----------------
具体观察者1做出反应...
具体观察者2做出反应...
*/

7.2 应用

八、中介者模式

中介模式:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的精合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

中介模式的主要角色:

  • 抽象中介者Mediator:中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法
  • 具体中介者Concrete Mediator:实现中介者接口,定义一个List来管理同事对象,协调各个同事角色的交互关系,因此它们依赖于同事角色
  • 抽象同事类Colleague:定义同时类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能
  • 具体同事类Concrete Colleague:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互

8.1 实现

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
public class MediatorPattern{
public static void main(String[] args){
Mediator md = new ConcreteMediator();
Colleague c1,c2;
c1 = new ConcreteColleague1();
c2 = new ConcreteColleague2();
md.register(c1);
md.register(c2);
c1.send();
System.out.println("--------------");
c2.send();
}
}

abstract class Mediator{
public abstract void register(Colleague colleague);
public abstract void relay(Colleague cl);
}

class ConcreteMediator extends Mediator{
private List<Colleague> colleagues = new ArrayList<Colleague>();

public void register(Colleague colleague){
if(!colleagues.contains(colleague)){
colleague.add(colleague);
colleague.setMedium(this);
}
}

public void relay(Colleague cl){
for(Colleague ob:colleagues){
if(!ob.equals(cl)){ // 传递请求给非cl的对象
((Colleague)ob).receive();
}
}
}
}

abstract class Colleague{
protected Mediator mediator;

public void setMedium(Mediator mediator){
this.mediator = mediator;
}
public abstract void receive();
public abstract void send();
}

class ConcreteColleague1 extends Colleague{
public abstract void receive(){
System.out.println("具体同事类1收到请求!");
}

public abstract void send(){
System.out.println("具体同事类1发出请求!");
mediator.relay(this) // 请中介者转发
}
}

class ConcreteColleague2 extends Colleague{
public abstract void receive(){
System.out.println("具体同事类2收到请求!");
}

public abstract void send(){
System.out.println("具体同事类2发出请求!");
mediator.relay(this) // 请中介者转发
}
}

/*
具体同事类1发出请求!
具体同事类2收到请求!
--------------
具体同事类2发出请求!
具体同事类1收到请求!
*/

8.2 应用

九、迭代器模式

迭代器Iterator模式:提供一个对象来 序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

迭代器模式的主要角色:

  • 抽象聚合Aggregate角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口
  • 具体聚合Concrete Aggregate角色:实现抽象聚合类,返回一个具体迭代器的实例
  • 抽象迭代器Iterator角色:定义访问和遍历聚合元素的接口,通常包含hasNext()、first()、next()等方法
  • 具体迭代器Concrete Iterator角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置

9.1 实现

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
public class IteratorPattern{
public static void main(String[] args){
Aggregate ag = new ConcreteAggregate();
ag.add("中山大学");
ag.add("华南理工");
ag.add("韶关学院");
System.out.println("聚合的内容有:");

Iterator it = ag.getIterator();
while(it.hasNext()){
Object ob = it.next();
System.out.println(ob.toString()+"\t");
}
Object ob = it.first();
System.out.println("\nFirst:"+ob.toString());
}
}

interface Aggregate{
public void add();
public void remove();
public Iterator getIterator();
}

class ConcreteAggregate implements Aggregate{
private List<Object> list = new ArrayList<>();

public void add(Object obj){
list.add(obj);
}

public void remove(Object obj){
list.remove(obj);
}

public Iterator getIterator(){
return new ConcreteIterator(list);
}
}

interface Iterator{
Object first();
Object next();
boolean hasNext();
}

class ConcreteIterator implements Iterator{
private List<Object> list = null;

private int index = 0;
public ConcreteIterator(List<Object> list){
this.list = list;
}

public boolean hasNext(){
if(index >= list.size()){
return false;
}else{
return true;
}
}

public Object first(){
index = 0;
Object obj = list.get(index);
return obj;
}

public Object next(){
Object obj = null;
if(this.hasNext()){
obj = list.get(index++);
}
return obj;
}
}

/*
聚合的内容有:中山大学 华南理工 韶关学院
First:中山大学
*/

9.2 应用

十、访问者模式

访问者模式:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。

访问者模式的主要角色:

  • 抽象访问者Visitor:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作visit(),该操作中的参数类型标识了被访问的具体元素
  • 具体访问者Concrete Vistor:实现抽象访问者角色中声明的各个访问操作
  • 抽象元素角色Element:声明一个包含接受操作accept()的接口,被接受的访问者对象作为accept()方法的参数
  • 具体元素角色Concrete Element:实现抽象元素角色提供的accept()操作,其方法体通常都是visitor.visit(this),另外具体元素中可能还包含本身业务逻辑的相关操作
  • 对象结构角色Object Structure:是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由List、Set、Map等聚合类实现

10.1 实现

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
89
90
91
92
93
94
95
96
97
98
public class VisitorPattern {
public static void main(String[] args) {
ObjectStructure os = new ObjectStructure();
os.add(new ConcreteElementA());
os.add(new ConcreteElementB());

Visitor visitor = new ConcreteVisitorA();
os.accept(visitor);
System.out.println("---------------------");
visitor = new ConcreteVisitorB();
os.accept(visitor);
}
}

interface Visitor{
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}

class ConcreteVisitorA implements Visitor{

@Override
public void visit(ConcreteElementA element) {
System.out.println("具体访问者A访问-->"+element.operationA());
}

@Override
public void visit(ConcreteElementB element) {
System.out.println("具体访问者A访问-->"+element.operationB());
}
}

class ConcreteVisitorB implements Visitor{

@Override
public void visit(ConcreteElementA element) {
System.out.println("具体访问者B访问-->"+element.operationA());
}

@Override
public void visit(ConcreteElementB element) {
System.out.println("具体访问者B访问-->"+element.operationB());
}
}

interface Element{
void accept(Visitor visitor);
}

class ConcreteElementA implements Element{

@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}

public String operationA(){
return "具体元素A的操作。";
}
}

class ConcreteElementB implements Element{

@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}

public String operationB(){
return "具体元素B的操作。";
}
}

class ObjectStructure{
private final List<Element> list = new ArrayList<>();
public void accept(Visitor visitor){
Iterator<Element> i = list.iterator();
while (i.hasNext()){
((Element) i.next()).accept(visitor);
}
}

public void add(Element element){
list.add(element);
}

public void remove(Element element){
list.remove(element);
}
}

/*
具体访问者A访问-->具体元素A的操作
具体访问者A访问-->具体元素B的操作
---------------------
具体访问者B访问-->具体元素A的操作
具体访问者B访问-->具体元素B的操作
*/

10.2 应用

十一、备忘录模式

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。

备忘录模式的主要角色:

  • 发起人Originator角色:记录当前时刻的内部状态信息,提供创建备忘录和回复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息
  • 备忘录Memento角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人
  • 管理者Caretaker角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问和修改

11.1 实现

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
public class MementoPattern {
public static void main(String[] args) {
Originator or = new Originator();
Caretaker cr = new Caretaker();
or.setState("S0");
System.out.println("初始状态:"+or.getState());

// 保存状态
cr.setMemento(or.createMemento());

or.setState("S1");
System.out.println("新的状态:"+or.getState());

// 恢复状态
or.restoreMemento(cr.getMemento());
System.out.println("恢复状态:"+or.getState());
}
}

class Memento{
private String state;

public Memento(String state){
this.state = state;
}

public void setState(String state){
this.state = state;
}

public String getState(){
return state;
}
}

class Originator{
private String state;

public void setState(String state){
this.state = state;
}

public String getState(){
return state;
}

public Memento createMemento(){
return new Memento(state);
}

public void restoreMemento(Memento m){
this.setState(m.getState());
}
}

class Caretaker{
private Memento memento;

public void setMemento(Memento m){
memento = m;
}

public Memento getMemento(){
return memento;
}
}
/*
初始状态:S0
新的状态:S1
恢复状态:S0
*/

11.2 应用

十二、解释器模式

解释器Interpreter模式的定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口。

解释器模式的主要角色:

  • 抽象表达式Abstract Expression:定义解释器的接口,约定解释器的解释操作,主要包含解释方法interpret()
  • 终结符表达式Terminal Expression:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应
  • 非终结符表达式Nonterminal Expression:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式
  • 环境角色Context:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值
  • 客户端Client:主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法

12.1 实现

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
/*文法规则
<expression>::=<city>的<person>
<city> ::= 韶关 | 广州
<person> ::= 老人 | 妇女 | 儿童
*/
public class InterpreterPatternDemo {
public static void main(String[] args) {
Context bus = new Context();
bus.freeRide("韶关的老人");
bus.freeRide("韶关的年轻人");
bus.freeRide("广州的妇女");
bus.freeRide("广州的儿童");
bus.freeRide("山东的儿童");
}
}

// 抽象表达类
interface Expression{
public boolean interpret(String info);
}

// 终结符表达式类
class TerminalExpression implements Expression{
private Set<String> set = new HashSet<>();

public TerminalExpression(String[] data){
for (int i=0;i<data.length;i++)
set.add(data[i]);
}

@Override
public boolean interpret(String info) {
if (set.contains(info)){
return true;
}
return false;
}
}

// 非终结表达式类
class NonTerminalExpression implements Expression{
private Expression city = null;
private Expression person = null;

public NonTerminalExpression(Expression city,Expression person){
this.city = city;
this.person = person;
}

@Override
public boolean interpret(String info) {
String s[] = info.split("的");
return city.interpret(s[0])&&person.interpret(s[1]);
}
}

// 环境类
class Context{
private String[] citys = {"韶关", "广州"};
private String[] persons = {"老人", "妇女", "儿童"};
private Expression cityPerson;

public Context(){
Expression city = new TerminalExpression(citys);
Expression person = new TerminalExpression(persons);
cityPerson = new NonTerminalExpression(city,person);
}

public void freeRide(String info){
boolean ok = cityPerson.interpret(info);
if (ok) System.out.println("您是"+info+",您本次乘车免费!");
else System.out.println(info+",您不是免费人员,本次乘车扣费20元!");
}
}

12.2 应用