设计模式-行为型模式(二)
七、观察者模式
观察者模式是指被观察者的状态发生改变时,系统基于事件驱动理论将其状态通知到订阅其状态的观察者对象中,以完成状态的修改和事件传播。
在观察者模式中,观察者和被观察者是抽象耦合的,两者之间建立了一套事件触发机制,以降低二者的耦合度。
观察者模式具体UML:
(1)定义抽象主题Subject:
public 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); } //notifyObserver方法用来实现消息发生变化时将改变后的消息发送给观察者 public abstract void notifyObserver(String message); }
(2)定义具体主题ConcreteSubject:
public class ConcreteSubject extends Subject { private final static Log logger = LogFactory.getLog(ConcreteSubject.class); @Override public void notifyObserver(String message) { for(Object obs:observers){ logger.info("观察者们注意--"+message+"--已经改变"); ((Observer)obs).dataChange(message); } } }
(3)定义抽象观察者:
public interface Observer { void dataChange(String message); }
(4)定义具体的观察者:
public class ConcreteObserver implements Observer { private final static Log logger = LogFactory.getLog(ConcreteObserver.class); @Override public void dataChange(String message) { logger.info("观察者收到--"+message+"--的消息"); } }
(5)使用观察者模式:
public class Main { public static void main(String[] args) { Subject subject = new ConcreteSubject(); Observer observer = new ConcreteObserver(); subject.add(observer); subject.notifyObserver("数据发生改变"); } }
结果:
十二月 31, 2019 5:42:56 下午 com.jzq.sign.Observer.ConcreteSubject notifyObserver 信息: 观察者们注意--数据发生改变--已经改变 十二月 31, 2019 5:42:56 下午 com.jzq.sign.Observer.ConcreteObserver dataChange 信息: 观察者收到--数据发生改变--的消息
八、迭代器模式
迭代器模式提供了可以顺序访问集合对象中的各个元素,而不暴露对象内部结构的方法。
以Collection为例:
(1)定义集合接口Collection:
public interface Collection { public Iterator iterator(); public Object get(int i); public boolean add(Object object); public int size(); }
(2)定义集合接口Collection的实现类ListCollection:
public class ListCollection implements Collection { public List list = new ArrayList(); @Override public Iterator iterator() { return new ConcreteIterator(this); } @Override public Object get(int i) { return list.get(i); } @Override public boolean add(Object object) { list.add(object); return true; } @Override public int size() { return list.size(); } }
(3)定义迭代器接口Iterator:
public interface Iterator { public Object previous(); public Object next(); public boolean hasNext(); }
(4)定义迭代器接口Iterator的实现类ConcreteIterator:
public class ConcreteIterator implements Iterator { private Collection collection; private int pos = -1; public ConcreteIterator(Collection collection) { this.collection = collection; } @Override public Object previous() { if(pos>0){ pos--; } return collection.get(pos); } @Override public Object next() { if(pos<collection.size()-1){ pos++; } return collection.get(pos); } @Override public boolean hasNext() { if(pos<collection.size()-1){ return true; }else{ return false; } } }
(5)使用迭代器:
public class Main { public static void main(String[] args) { Collection collection = new ListCollection(); collection.add("object1"); collection.add("object2"); collection.add("object3"); Iterator it = collection.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }
结果:
object1
object2
object3
九、备忘录模式
备忘录模式保存一个对象的某个状态,以便在适当的时候将该对象的状态恢复到原先保存的状态。
给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
具体UML:
(1)定义原始数据Original:
public class Original { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Original(String value) { this.value = value; } public Memento createMemento(){ return new Memento(value); } public void restoreMemento(Memento memento){ this.value = memento.getValue(); } }
(2)定义备忘录Memento:
public class Memento { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Memento(String value) { this.value = value; } }
(3)定义备忘录管理员Storage:
public class Storage { private Memento memento; public Storage(Memento memento) { this.memento = memento; } public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } }
(4)使用备忘录模式:
public class Main { public static void main(String[] args) { Original original = new Original("大枪"); Storage storage = new Storage(original.createMemento()); System.out.println("原始值为"+original.getValue()); original.setValue("小枪"); System.out.println("现值为"+original.getValue()); original.restoreMemento(storage.getMemento()); System.out.println("恢复之后值为"+original.getValue()); } }
结果:
原始值为大枪
现值为小枪
恢复之后值为大枪
十、状态模式
状态模式指给对象定义不同的状态,并为不同状态定义不同的行为,在对象状态发生变化时自动切换状态。
何时使用:代码中包含大量与对象状态有关的条件语句。
以工作状态为例:
(1)定义AbstractState:
public abstract class AbstractState { public abstract void action(Context context); }
(2)定义AbstractState的子类HolidayState、WorkState:
public class HolidayState extends AbstractState { private final static Log logger = LogFactory.getLog(HolidayState.class); @Override public void action(Context context) { logger.info("状态转为假期"); logger.info("holiday action is travel, shopping,watch TV"); } } public class WorkState extends AbstractState { private final static Log logger = LogFactory.getLog(WorkState.class); @Override public void action(Context context) { logger.info("状态转为工作日"); logger.info("work state action is coding, meeting, design"); } }
(3)定义Context用于存储状态和执行不同状态下的行为:
public class Context { private AbstractState state; public AbstractState getState() { return state; } public void setState(AbstractState state) { this.state = state; } public Context(AbstractState state) { this.state = state; } public void action(){ this.state.action(this); } }
(4)使用状态模式:
public class Main { public static void main(String[] args) { Context context = new Context(new WorkState()); context.action(); context.setState(new HolidayState()); context.action(); } }
结果:
十二月 31, 2019 9:02:47 下午 com.jzq.sign.State.WorkState action 信息: 状态转为工作日 十二月 31, 2019 9:02:47 下午 com.jzq.sign.State.WorkState action 信息: work state action is coding, meeting, design 十二月 31, 2019 9:02:47 下午 com.jzq.sign.State.HolidayState action 信息: 状态转为假期 十二月 31, 2019 9:02:47 下午 com.jzq.sign.State.HolidayState action 信息: holiday action is travel, shopping,watch TV
十一、中介者模式
中介者模式是将对象与对象之间的关系变为对象与中介者之间的关系,通过定义不同的中介者来改变对象之间的交互,降低对象之间的耦合度。
以租房为例:
(1)定义抽象类Colleague类:
public abstract class Colleague { protected Mediator mediator; public void setMediator(Mediator mediator) { this.mediator = mediator; } public abstract boolean operation(String message); }
(2)定义Colleague实现类ColleagueLandlord代表房东:
public class ColleagueLandlord extends Colleague { private final static Log logger = LogFactory.getLog(ColleagueLandlord.class); @Override public boolean operation(String message) { logger.info("房东收到一条来自中介的信息--" + message); return true; } }
(3)定义Colleague实现类ColleagueTenant代表找房人:
public class ColleagueTenant extends Colleague { private final static Log logger = LogFactory.getLog(ColleagueTenant.class); @Override public boolean operation(String message) { logger.info("找房人收到一条来自中介的信息--" + message); return true; } }
(4)定义中介者Mediator抽象类:
public abstract class Mediator { protected Colleague colleagueTenant; protected Colleague colleagueLandlord; public Mediator(Colleague colleagueTenant, Colleague colleagueLandlord) { this.colleagueTenant = colleagueTenant; this.colleagueLandlord = colleagueLandlord; } //向找房人发送消息 public abstract boolean notifyColleagueTenant(String message); //向房东发送消息 public abstract boolean notifyColleagueLandlord(String message); }
(5)定义Mediator实现类ConcreteMediator代表具体中介:
public class ConcreteMediator extends Mediator { public ConcreteMediator(Colleague colleagueTenant, Colleague colleagueLandlord) { super(colleagueTenant, colleagueLandlord); } @Override public boolean notifyColleagueTenant(String message) { if(colleagueTenant != null){ return colleagueTenant.operation(message); } return false; } @Override public boolean notifyColleagueLandlord(String message) { if(colleagueLandlord != null){ return colleagueLandlord.operation(message); } return false; } }
(6)使用中介者模式:
public class Main { public static void main(String[] args) { Colleague colleagueTenant= new ColleagueTenant(); Colleague colleagueLandlord= new ColleagueLandlord(); ConcreteMediator concreteMediator = new ConcreteMediator(colleagueTenant,colleagueLandlord); boolean result = concreteMediator.notifyColleagueTenant("现有一室一厅,想租吗?"); if(result){ concreteMediator.notifyColleagueLandlord("租客很满意"); }else{ concreteMediator.notifyColleagueLandlord("租客不满意"); } } }
结果:
十二月 31, 2019 9:51:17 下午 com.jzq.sign.Mediator.ColleagueTenant operation 信息: 找房人收到一条来自中介的信息--现有一室一厅,想租吗? 十二月 31, 2019 9:51:17 下午 com.jzq.sign.Mediator.ColleagueLandlord operation 信息: 房东收到一条来自中介的信息--租客很满意