本文承接上一篇设计模式总结内容,继续总结介绍行为型模式的后六种模式:观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式和解释器模式。
一、观察者模式
观察者模式,又叫做发布-订阅模式,是指多个对象之间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。现实情境中公众号和订阅者、天气预报和听众等都是观察者模式。
观察者模式包括以下角色:抽象主题、具体主题、抽象观察者、具体观察者。
观察者模式的关键在于将目标与观察者进行分离,通过在目标类中封装观察者对象数组链表,实现观察者与目标之间的松耦合,当目标需要通知观察者时,只需遍历观察者列表,让观察者对象执行反应方法即可。(Vue双向数据绑定即使用了观察者模式)
public class ObserverTest {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer ob1 = new ConcreteObserver1();
Observer ob2 = new ConcreteObserver2();
subject.add(ob1);
subject.add(ob2);
subject.notifyObserver();
}
}
//抽象目标
abstract class Subject {
protected List<Observer> 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 obj : observers) {
((Observer) obj).response();
}
}
}
//抽象观察者
interface Observer {
void response();
}
//具体观察者1
class ConcreteObserver1 implements Observer {
public void response() {
System.out.println("具体观察者1作出反应");
}
}
//具体观察者2
class ConcreteObserver2 implements Observer {
public void response() {
System.out.println("具体观察者2作出反应");
}
}
程序运行结果输出如下:
具体目标发生改变...
---------
具体观察者1作出反应
具体观察者2作出反应
二、中介者模式
中介者模式,又叫做调停模式,是指定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。现实情境中的好友通讯录、城市信息中心等都是中介者模式。
中介者模式包含以下角色:抽象中介者、具体中介者、抽象同事类、具体同事类。
中介者模式的关键在于让中介者类负责保存和管理同事对象,从而避免了同事对象之间的强绑定关系,这一点与观察者模式十分相似。然而,观察者模式仅能让目标对象单向通知所有目标观察者,而中介者只是作为交互的媒介,其中保存的同事对象均可以发送和接收信息,只不过发送和接收均是通过中介者传递实现。(Socket的简单广播实现即使用中介者模式)
public class MediatorTest {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
Colleague c1 = new ConcreteColleague1();
Colleague c2 = new ConcreteColleague2();
mediator.register(c1);
mediator.register(c2);
c1.send();
System.out.println("--------------");
c2.send();
}
}
//抽象中介者
abstract class Mediator {
//注册
public abstract void register(Colleague colleague);
//转发
public abstract void relay(Colleague colleague);
}
//具体中介者
class ConcreteMediator extends Mediator {
private List<Colleague> colleagues = new ArrayList<Colleague>();
public void register(Colleague colleague) {
if (!colleagues.contains(colleague)) {
colleagues.add(colleague);
colleague.setMedium(this);
}
}
public void relay(Colleague colleague) {
for (Colleague cl : colleagues) {
if (!cl.equals(colleague)) {
cl.receive();
}
}
}
}
//抽象同事类
abstract class Colleague {
protected Mediator mediator;
//设置中介者
public void setMedium(Mediator mediator) {
this.mediator = mediator;
}
//接收消息
public abstract void receive();
//发送消息
public abstract void send();
}
//具体同事类1
class ConcreteColleague1 extends Colleague {
public void receive() {
System.out.println("具体同事1收到请求");
}
public void send() {
System.out.println("具体同事1发出请求");
mediator.relay(this);//请求中介者转发
}
}
//具体同事类2
class ConcreteColleague2 extends Colleague {
public void receive() {
System.out.println("具体同事2收到请求");
}
public void send() {
System.out.println("具体同事2发出请求");
mediator.relay(this);//请求中介者转发
}
}
程序运行结果输出如下:
具体同事1发出请求
具体同事2收到请求
--------------
具体同事2发出请求
具体同事1收到请求
三、迭代器模式
迭代器模式是指提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象内部表示的设计模式,在客户访问类与聚合类之间插入一个迭代器,分离了聚合对象与其遍历行为,对客户也隐藏了其内部细节。
迭代器模式包含以下角色:抽象聚合角色、具体聚合角色、抽象迭代器角色、具体迭代器角色。
public class IteratorTest {
public static void main(String[] args) {
Aggregate aggregate = new ConcreteAggregate();
aggregate.add("观察者模式");
aggregate.add("中介者模式");
aggregate.add("迭代器模式");
System.out.println("聚合的内容有:");
Iterator iterator = aggregate.getIterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.print(obj.toString() + "\t");
}
Object obj = iterator.first();
System.out.println("\nFirst:" + obj.toString());
}
}
//抽象聚合
interface Aggregate {
void add(Object obj);
void remove(Object obj);
Iterator getIterator();
}
//具体聚合类
class ConcreteAggregate implements Aggregate {
private List<Object> list = new ArrayList<Object>();
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 = -1;
public ConcreteIterator(List<Object> list) {
this.list = list;
}
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;
}
public boolean hasNext() {
if (index < list.size() - 1) {
return true;
} else {
return false;
}
}
}
程序运行结果输出如下:
聚合的内容有:
观察者模式 中介者模式 迭代器模式
First:观察者模式
四、访问者模式
访问者模式是指将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。现实情境中不同读者对一本书的看法、不同职业对一件商品的关注角度等都是访问者模式。
访问者模式包含以下角色:抽象访问者、具体访问者、抽象元素、具体元素、对象结构。
访问者模式的关键在于将访问者与被访问元素进行分割,通过对象结构类保存和管理被访问者(具体元素)对象列表,在执行访问方法时将具体访问者与被访问对象列表进行动态绑定,从而实现特定访问者的访问结果。
public class VisitorTest {
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);
}
//具体访问者A类
class ConcreteVisitorA implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者A访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者A访问-->" + element.operationB());
}
}
//具体访问者B类
class ConcreteVisitorB implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("具体访问者B访问-->" + element.operationA());
}
public void visit(ConcreteElementB element) {
System.out.println("具体访问者B访问-->" + element.operationB());
}
}
//抽象元素类
interface Element {
void accept(Visitor visitor);
}
//具体元素A类
class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationA() {
return "具体元素A的操作";
}
}
//具体元素B类
class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationB() {
return "具体元素B的操作";
}
}
//对象结构类
class ObjectStructure {
private List<Element> list = new ArrayList<Element>();
public void accept(Visitor visitor) {
Iterator<Element> iterator = list.iterator();
while (iterator.hasNext()) {
iterator.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的操作
五、备忘录模式
备忘录模式,又叫做快照模式,是指在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便于以后当需要时能够将该对象恢复到原先保存的状态的模式。现实情境中的各类软件撤回功能都是备忘录模式。
备忘录模式包含以下角色:发起者、备忘录、管理者。
备忘录模式的关键在于状态的外部保存。状态发起者和备忘录中均封装了state属性,通过管理者对备忘录对象的封装可以实现不同状态的备忘录对象创建与更新获取,从而在需要状态回退时,发起者只需要向管理者调用获取备忘录并重置内部状态即可实现。
public class MementoTest {
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 String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
//发起者
class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento createMemento() {
return new Memento(state);
}
public void restoreMemento(Memento m) {
this.setState(m.getState());
}
}
//管理者
class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
程序运行结果输出如下:
初始状态:S0
新的状态:S1
恢复状态:S0
六、解释器模式
解释器模式是指给分析对象定义一种语言,并定义改语言的语法表示,再设计一个解释器来解释语言中的句子的模式。
解释器模式包含以下角色:抽象表达式、终结符表达式、非终结符表达式、环境、客户端
解释器模式在此不做赘述,有兴趣的可以单独搜索研究。
本文主要参考:http://c.biancheng.net/