??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
涉及的面向对象设计原则:单一职责原则、封装变化、面向接口编E、依赖倒置原则、开闭原则?/span>
1.发布订阅模型Q?
假如有需求如?
银行需要把帐户的如汇款、{账或取款{操作通知用户Q途径包括手机短信?email{。如图所式?br>
自然圎ͼ我们可以q样做:
{
BankAccount bankAccount;
public void process()
{
//bankAccount...
this.sendEmail(userEmail);
this.sendPhone(phoneNumber);
}
private void sendEmail(String userEmail)
{
//
}
private void sendMobile(String phoneNumber)
{
//
}
}
ATM机的 process()Ҏ(gu)在处理完业务逻辑后,由email和phone通知用户?br>
2.初步重构
好像有bad smellsQ恩Q根?span style="COLOR: #049a0e">单一职责原则。新增EmailcdPhonec,q把相关业务逻辑改到BankAccountcd成。于是我们的代码可以q样Q?br>
public class ATM
{
BankAccount bankAccount;
public void process()
{
//
bankAccount.withDraw();
}
}
public class BankAccount
{
Email email;
Mobile mobile;
public void withDraw()
{
//
email.sendEmail(userEmail);
mobile.sendMobile(phoneNumber);
}
}
public class Email
{
public void sendEmail(String userEmail)
{
}
}
public class Mobile
{
public void sendMobile(String phoneNumber)
{
}
}
下面是代码的UML图:
3.拥抱变化
q个解决Ҏ(gu)有问题吗?可能没有问题。它实现了我们的需求:在帐h操作变动的时候,通知Email和Mobiled送信息给用户。但q样设计p够了吗?可能_了,可能q不够?br>考虑如下两种情况Q?br>1.在很长一D|间里Q订阅方式很E_Q比如系l只通过邮g和手机短信进行信息订阅,那么q个实现没有太大问题Q?br>2.在近一两年或更短的旉Q更多的订阅方式会源源不断地被加进来:比如可以d官方|站{等Q那q个实现有问题Q再看一下我们的UML图,cBankAccount依赖于Email和Mobilec!是_如果需要添加新的订阅方式ATMcȝprocess()Ҏ(gu)势必要重新设计!
于是我们的BankAccountcM得不变成Q?br>
{
Email email;
Mobile mobile;
Web web;
public void withDraw()
{
//
email.sendEmail(userEmail);
mobile.sendMobile(phoneNumber);
web.sendWeb(webSite);
}
}
如果q有另一U方式,那么process()Ҏ(gu)又会需要加入:otherSubscribe.send...();{方法,另外如果订阅cȝ接口(q里指sendEmail{方?发生变化QBankAccount的withDraw()Ҏ(gu)也必L相应的变化!q当然是U灾难。我们必L变这U情c?br>先解决遗留问题:W一U情况:订阅方式相对E_的情况下呢?不改动会产生N吗?
个h认ؓQ不会。比如某个系l信息只通过手机短信订阅Q那没有必要太在意q个问题。考虑周全一点不好吗Q如果将来有cM需求呢Q小?span style="COLOR: red">q度设计Qؓ了将来可能出现需求而进行的预先设计q不太好。有需求,才有设计?br>
现在来看解决之道Q?br>
q用面向对象的思想Q抽象出问题所在。BankAccountcM赖于 EmailcdMobilec,而Email和Mobile是具体的c,ATM依赖于具体的c?/span>了,而且q不止一个!回忆一?span style="COLOR: #2000ff">依赖倒置原则Q具体应该依赖于抽象Q底层模式应该依赖于高层模式?/span>那怎么实现依赖倒置原则?面向对象~程中有一条ȝ原则Q?span style="COLOR: #049a0e">装变化。如何实?span style="COLOR: #049a0e">装变化Q需要我们这P面向接口~程?/span>
回顾一下:我们在设计中实现cM赖了具体的类Q违反了依赖倒置原则。ؓ了遵循依赖倒置原则Q我们采用面向接口编E的Ҏ(gu)Q从而实C面向对象的一条ȝ原则Q封装变化?/span>
看代码:
{
public void upDate(UserAccount userAccount);
}
public class Email implements AccountObserver
{
public void upDate(UserAccount userAccount)
{
}
}
public class Mobile
{
public void upDate(UserAccount userAccount)
{
}
}
public class BankAccount
{
List <AccountObserver> observer = new ArrayList<AccountObserver>;
public void withDraw()
{
//
for (AccountObserver ao : observer)
{
ao.upDate(userAccount)
}
}
public void addOberver(AccountObserver accountObserver)
{
observer.add(accountObserver);
}
}
UML图:
现在QBankAccount依赖于interface AccountObserver。Email和Mobile实现AccountObserver接口?span style="COLOR: #049a0e">通过遵@面向接口~程遵@?span style="COLOR: #049a0e">依赖倒置原则?/span>
4.开闭原?/span>
l于修改好了Q我们解决了订阅者变化的问题。但如果发布者也們于变化呢Q这q涉到面向对象里的另一个原则:开闭原?/span>?span style="COLOR: #049a0e">卻IҎ(gu)展开放,对修改关闭?/span>具体怎么做呢Q通过抽象c,从抽象类l承具体cR?br>看最l的代码(只写几个关键的方法,全貌可看最后的UML?Q?br>
订阅Q?
{
public void upDate(UserAccount userAccount);
}
public class Email implements AccountObserver
{
public void upDate(UserAccount userAccount)
{
}
}
public class Mobile implements AccountObserver
{
public void upDate(UserAccount userAccount)
{
}
}
发布Q?br>
public abstract class Subject
{
List <AccountObserver> observer = new ArrayList<AccountObserver>;
protected void withDraw()
{
//
notify();
}
protected void notify(UserAccount userAccount)
{
for (AccountObserver ao : observer)
{
ao.upDate(userAccount)
}
}
protected void addOberver(AccountObserver accountObserver)
{
observer.add(accountObserver);
}
protected void deleteOberver(AccountObserver accountObserver)
{
observer.remove(accountObserver);
}
}
public class BankAccount extends Subject
{
public void withDraw()
{
//
for (AccountObserver ao : observer)
{
ao.upDate(userAccount)
}
}
}
看UML图:
5.观察者模式概?/span>
q就是观察者模式了Q对比一下官方的UML图,是不是一目了然了呢?
E作说明(q里的依赖都是指q义的依?Q?br>1.被观察者ConcreteSubjectl承自Subject抽象c;
2.Subject抽象cM赖于观察者Observer抽象接口Q?br>3.观察者ConcreteObserver实现Observer 接口Q?br>4.观察者ConcreteObserver间接依赖于ConcreteSubjectcR?br>如果要增加具体的观察者,只要再实现Obsever接口卛_Q而被观察方不需要做M修改。而如果需要修改被观察者,只要从Subject抽象cȝ承即可?br>
]]>
http://www.otasuke.ne.jp/modules/xwords/index.php
http://jp.hjenglish.com/papers.aspx
www.21cnhr.gov.cn
http://www.ytv.co.jp/conan/
http://www13.tianya.cn/new/Publicforum/Content.asp?idWriter=3915484&Key=228823315&strItem=no04&idArticle=483393&flag=1
http://piano.stedu.net/
http://www.nhk.or.jp/ <<NHK>> http://www.nhk.or.jp/r-news/
http://www.intel.com/software/cn/mcwebcast/#slide=1 intel class
http://www.yangmi.net/ky/Print.asp?ArticleID=13801 Q!Q?nbsp;
http://bbs.i18.cn/index.asp 中国零售|?nbsp;
http://www.fortunespace.net/forum/ 中国財富論壇
http://www.yesky.com/SoftChannel/72357786515668992/20040129/1764106.shtml 求和
http://www.yesky.com/SoftChannel/72348968914255872/20050126/1905902.shtml Excel ??nbsp;
http://www.yesky.com/soft/office/excel-news/his/his_4.shtml Excel
http://www.4399.net/flash/1602_2.htm?800 golden
http://edu.itbulo.com/200511/58025.htm ITbulo
http://202.103.49.240/jsjzs/excel/excelyy.htm Excel 排序
http://192.168.1.23/use_wf/Dep_App WF WF WF WF
http://www.yodian.com 有点
http://www.dlsp.com.cn DLSP
http://64.233.179.104/search?q=cache:QqZYnKlqqEwJ:members.at.infoseek.co.jp/skillup/yougo/yougo6.htm+EOB%E3%80%80Electronic&hl=ja&gl=jp&ct=clnk&cd=1&lr=lang_ja
http://www.codesky.net CODE
http://www1.tianya.cn/new/TechForum/Content.asp?idWriter=3915484&Key=840161655&idItem=81&idArticle=251915
http://www.chinacs.net/archives/8/2004/12/12/3188.html C#
http://music.whnews.cn/playgame/flashshow.php?flashid=895 SC
http://www.tianya.cn/new/TechForum/Content.asp?idWriter=3915484&Key=481775086&idItem=81&idArticle=562447
http://192.168.1.211/TRIAL/upload/jinji/study/access/ ACCESS
http://www.wswire.com/ huaerjie dianxun
http://infoseek.amikai.com/amitext/indexUTF8.jsp
http://www.51windows.net/pages/ado/?url=/pages/ado/mdmthaddnew.htm ADO ADO
http://www.51windows.net/
http://www.codechina.net/resource/sort.php/621/4 Access VBA Code
http://jakarta.apche.org struts
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/csref/html/vcoricsharptutorials.asp MSDN c#
http://www.daliancity.com.cn/job/index.php DLZX
http://www.cjsdu.com/ DuiRiLunTan
http://www.mutouyu.com/translation/ 木頭翻a?/p>
http://localhost:8080/solves4/pages/CM/AAA/CMAAA001R.jsp
http://www2.tianya.cn/new/techforum/Content.asp?idWriter=3915484&Key=677920263&idItem=81&idArticle=573828
hua xian chuang guan
http://www.4399.net/flash/4362_4.htm?1024
pao tai TD
http://www.excite.co.jp/world/chinese/
onlineTranslate
http://www.4399.net/flash/457_1.htm?800
qiJi
http://www.javaeye.com/
http://www.andykhan.com/jexcelapi/
JXL(JAVA Excel API)
http://www.uml.org.cn/sjms/200703274.asp
a計モー?/p>
http://www.okajax.com/
Ajax 中国
http://www.nicenic.com/domain/
域名
域名最长的|站
http://www.llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch.co.uk/
http://www.111111111111111111111111111111111111111111111111111111111111.com/
http://3.141592653589793238462643383279502884197169399375105820974944592.com/
http://www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com/
几个不错的JAVA学习|站
http://www.csdn.net(C、文档、bolg、知识库)
http://www.hibernate.org.cn
http://www.aygfsteel.com
http://www.jdon.com
http://www.javafan.net
http://www.open-open.com
http://dev2dev.bea.com.cn/
http://www.javaresearch.org/
http://www.codechina.net/resource/
http://gceclub.sun.com.cn
http://www.javaeye.com
http://WWW.chinaitlab.com 中国IT試験?/p>
(zhn)的Blog地址?http://www.aygfsteel.com/lyl3333489/