C7) Observer(观察者模式) 定义:在对象间建立一对多的关联,使得一旦一个对象改变其状态,所有其关联对象都会自动地被通知并且更新。 非常有用的一个行为模式,同样关心状态的改变,与中介模式倒是有几分相似。观察者模式相比中介模式采取更加主动的方式,即由被观察者也就是状态改变的对象主动通知所有观察它变化的对象实行更新,无需通过中介转发,而且改变观察者或改变更新逻辑时几乎不需要对原有代码进行改动,相比中介模式来的更加灵活,耦合度也低。但是如果要进行相互观察,可能就会产生预想不到的死循环。还是借用中介模式的例子来说明。 先定义观察者的接口: public interface Observer { void update(Observable o, Object arg); } 被观察者对象: public class Observable { private boolean changed = false; private List observers = new ArrayList(); public void notifyObservers(Object arg) { Iterator itr = observers.iterator(); while (itr.hasNext()) { (Observer)(itr.next()).update(this, arg); } } public void setChanged() { this.changed = true; } public void clearChanged() { this.changed = false; } } 这样,菜单为被观察者: public class SetupMenu extends Observable { private Map itemMap; public void notifyObservers() { notifyObservers(itemMap); } public void select() { setSelected(true); notifyObservers(); } } 多选框为观察者: public class SetupItem implements Observer { private String Name; void update(Observable o, Object arg) { if ((Map)arg.containsKey(this.Name)) this.checked = true; else this.checked = false; } } 只需将所有多选框都添加到observers中去,然后设置每个菜单显示的多选框itemMap,当菜单被选中后,调用notifyObservers()来通知所有观察它的对象(这里就是所有多选框)进行更新。 SetupMenu menu = new SetupMenu("Mini"); menu.addObserver(new SetupItem("Core")); //添加到observers menu.addObserver(new SetupItem("VideoDecode")); .... //全部SetupItem menu.addItem("Core"); //添加到itemMap menu.addItem("VideoDecode"); .... //关联SetupItem 通过menu.select()就可以发现Item的变化。 突然想到前几天项目中DB处理上的一个问题,主表的一条记录修改或者删除后,所有以主表为参照表的子表记录也需要被修改或删除,像是公司与公司详细、公司财务、公司业绩这几张表的关系,删除了公司,公司所有附属信息也要一并删除,这时也可以考虑使用这种模式,增加公司部门表后,也只需多添加一个observer就可以了。
参考: 1、 http://www./designpatterns/observer.htm(中文、java实例) 2、 http://www./Patterns/PatternObserver.aspx(英文、C#实例、UML) 3、 http://www.caterpillar./PmWiki/pmwiki.php/DesignPattern/ObserverPattern(中文、java实例、UML)推荐
|