﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-J2EE,Documentum,GWT,EJB学习路程-随笔分类-战斗总结</title><link>http://www.blogjava.net/todd841026/category/21424.html</link><description>为了所爱的，和爱我的人努力</description><language>zh-cn</language><lastBuildDate>Mon, 09 Apr 2007 03:05:30 GMT</lastBuildDate><pubDate>Mon, 09 Apr 2007 03:05:30 GMT</pubDate><ttl>60</ttl><item><title>2007.3.25-2007.4.6战斗中----观察者模式实践                 我的所有随笔属于个人总结，有不足之处请回复指出</title><link>http://www.blogjava.net/todd841026/archive/2007/04/07/ObserverPattern.html</link><dc:creator>田亮</dc:creator><author>田亮</author><pubDate>Fri, 06 Apr 2007 19:00:00 GMT</pubDate><guid>http://www.blogjava.net/todd841026/archive/2007/04/07/ObserverPattern.html</guid><wfw:comment>http://www.blogjava.net/todd841026/comments/109050.html</wfw:comment><comments>http://www.blogjava.net/todd841026/archive/2007/04/07/ObserverPattern.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/todd841026/comments/commentRss/109050.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/todd841026/services/trackbacks/109050.html</trackback:ping><description><![CDATA[&nbsp;
<p><span>观察者模式体验就是一个：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>问题：在做</span><span>UI</span><span>设计时，遇到一个问题，就是当我点击一个自定义对话框的复选框时，自定义对话框的父界面必须做出相应的改变，还有，自定义对话框是做成的组件，应用于很多场合（有很多的界面用到此对话框）；</span></p>
<p><span>//</span><span>这是自定义的对话框，当事件是</span><span>checkbox</span><span>时，让父界面做</span><span>//</span><span>出改变</span></p>
<p><span>Public class DialogBox implements ClickListener {</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void onClick(event e){</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span>//</span><span>这是父界面，他弹出对话框</span></p>
<p><span>Public class ParentFrame extends ParentClass{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void popDialogBox(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DialogBox dialogbox = new DialogBox(this) ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>解决方案一：</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>我把父界面的父类改变成自定义的父类，让父界面继承自定义的父类：</span></p>
<p><span>Public class DialogBox implements ClickListener{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Private Ojbect object = null ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Private CheckBox checkbox = new CheckBox() ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public DialogBox(Ojbect object){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.object = object ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Public void onClick(event e){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>If(e == checkbox){</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span>当事件是</span><span>checkbox</span><span>时，强制转换成</span><span>Custom</span><span>调用</span><span>//update</span><span>方法</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>((Custom)object).update();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span>//</span><span>这是自定义类，它继承了</span><span>ParentClass,</span><span>并抽象了个</span><span>update</span><span>方</span><span>//</span><span>法</span></p>
<p><span>Public abstact CustomClass extends ParentClass{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public abstract void update() ;</span></p>
<p><span>}</span></p>
<p><span>Public class ParentFrame extends CustomClass {</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void popDialogBox(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DialogBox dialogbox = new DialogBox(this) ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void update(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span><span>父界面的更新操作</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span>这个解决方案确实解决的问题，当自定义对话框点击</span><span>checkbox</span><span>时，确实会使他的父界面发生改变，但他的缺点太大：必须继承</span><span>CustomClass</span><span>才能具备这样的功能，而且主要是因为他改变了继承关系，在</span><span>ParentFrame</span><span>和</span><span>ParentClass</span><span>之间加了一层，这样使耦合度加大了；而且每次都把自身的引用通过构造传过去（</span><span>new DialogBox(this)</span><span>），在</span><span>dialogbox</span><span>那边还要强行转换回来，确实不是什么好办法</span><span><span>J</span></span></p>
<p><span>解决方案二：</span></p>
<p><span>//</span><span>定义</span><span>CustomListener</span><span>接口</span></p>
<p><span>Public interface CustomListener (){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void update() ;</span></p>
<p><span>}</span></p>
<p><span>Public class DialogBox implements ClickListener{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Private Ojbect object = null ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Private CheckBox checkbox = new CheckBox() ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public DialogBox(Ojbect object){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.object = object ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Public void onClick(event e){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>If(e == checkbox){</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span>当事件是</span><span>checkbox</span><span>时，强制转换成</span><span>Custom</span><span>调用</span><span>//update</span><span>方法</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>((CustomListener)object).update();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span>//</span><span>实现了</span><span>CustomListener</span><span>接口</span></p>
<p><span>Public class ParentFrame extends ParentClass implements CustomListener {</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void popDialogBox(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DialogBox dialogbox = new DialogBox(this) ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void update(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span><span>父界面的更新操作</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span>这个解决方案也是解决了问题，尤其对第一解决方案而言，这个已经不会打乱继承关系，但是还没有脱离第二个缺陷；</span></p>
<p><span>解决方案三：</span></p>
<p><span>//</span><span>定义</span><span>Listener</span><span>接口</span></p>
<p><span>Public interface CustomListener(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void update() ;</span></p>
<p><span>}</span></p>
<p><span>//</span><span>定义</span><span>event</span><span>接口</span></p>
<p><span>Public interface CustomEvent(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void addCustomListener(CustomListener listener) ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void removeCustomListener(CustomListener listner) ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void notify() ;</span></p>
<p><span>}</span></p>
<p><span>Public class DialogBox implements ClickListener, CustomEvent {</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Private List listenerList = new ArrayList() ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Private CheckBox checkbox = new CheckBox() ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public DialogBox(Ojbect object){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>this.object = object ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Public void onClick(event e){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>If(e == checkbox){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>notify() ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span>注册一个观察者</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Public void addCustomListener(CustomListener listener) {</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>listenerList.add(listener) ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span>删除一个观察者</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void removeCustomListener(CustomListener listner){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>listenerList.remove(listener) ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</span><span>调用所以注册的观察者</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void notify() {</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>If(listenerList != null &amp;&amp; !( listenerList.isEmpty)){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>for(int I = 0 ; I &lt; listenerList.size() ; I ++){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((CustomListener)listenerList.get(i)).update();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span>//</span><span>实现了</span><span>CustomListener</span><span>接口</span></p>
<p><span>Public class ParentFrame extends ParentClass implements CustomListener {</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void popDialogBox(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>DialogBox dialogbox = new DialogBox() ;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>dialogbox. addCustomListener((CustomListener)this) ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Public void update(){</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>//</span><span>父界面的更新操作</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>}</span></p>
<p><span>第三中解决方案才是观察者模式是应用，这才是较为合理的方案；</span></p>
<p><span>观察者模式应用前提是：有一个对象出发事件时，其他对象也发生改变；是个一对多的关系</span></p>
<img src ="http://www.blogjava.net/todd841026/aggbug/109050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/todd841026/" target="_blank">田亮</a> 2007-04-07 03:00 <a href="http://www.blogjava.net/todd841026/archive/2007/04/07/ObserverPattern.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>