设计模式初学者教程(下)
Good cooking takes time. If you are made to wait, it is to serve you better, and to please you.
(美酒的酿造需要年头,美食的烹调需要时间;片刻等待,更多美味,更多享受。)
—— 《人月神话》
写在前面
本文的内容主要来源于前段时间的部门分享,经过整理、修订与完善后,现分享给各位,祝开卷有益。
适配器模式While in rome , do as rome dose
假设您所维护的应用暴露出来的接口与现有服务商提供的接口相冲突……
您可以通过实现一个适配器来使两者“相匹配”

现在,由于适配器的引入,您的应用又可以正常工作了,而不用去修改现有系统或厂商类的代码了
还记得全聚德的鸭子们吗?它们现在又碰到了麻烦。由于现在鸭肉紧缺,公司准备用火鸡来代替,但却发觉之前的系统似乎失灵了……
恩,这似乎是显而易见的,之前的系统是针对鸭子接口的,当然不能用于火鸡的实例,要搞清楚的事,火鸡从不呱呱叫(quack),只会咯咯叫(gobble);火鸡由于体型的缘故,飞行距离很短;另外,您见过会游泳的火鸡吗?!
鸭子和火鸡的抽象超类和具体实现类如下所示:
public interface Duck { //鸭子的接口…… public void quack(); public void fly(); public void swim();}public class MallardDuck implements Duck { //绿头鸭的具体实现…… public void quack() { System.out.println("Quack"); } public void fly() { System.out.println("fly"); } public void swim() { System.out.println("swim"); }}public interface Turkey { //火鸡的接口……public void gobble(); public void fly();}public class WildTurkey implements Turkey { //野生火鸡的具体实现…… public void gobble() { System.out.println("Gobble"); } public void fly() { System.out.println("Flying a short distance"); }}public class TurkeyAdapter implements Duck { //首先,你必须实现你想要转换成的、客户 所期望看到的类型接口(Duck) Turkey turkey; public TurkeyAdapter(Turkey turkey){ //必须采用某种方式,获得需要适配的对象的引用, 比如构造器注入… this.turkey = turkey; } public void quack() { //有些方法需要简单转换,比如用火鸡的咯咯叫(gobble)来代替鸭子的呱呱叫(quack) turkey.gobble(); } public void fly() { //有些方法需要复杂抓换,比如,由于火鸡的飞行距离较短,要达到鸭子的飞行效果,火鸡需要加倍的努力哦(调用fly五次) for (int i=0; i<5; i++) { turkey.fly(); } } public void swim() { //还有些方法无法适配,这是可以覆盖为空、或者抛出异常、或者干脆像火鸡一样说:“这个我干不了”? System.out.println("No Turkey can SWIM!!!"); }}



public class Enumeration implements Iterator { //因为我们要将枚举适配成迭代器,因此必须要实现迭代器(被适配者)接口,让它看起来就像是一个迭代器 Enumeration enum; public EnumerationIterator(Enumeration enum) { //利用组合的方式,保存一个枚举的引用 this.enum = enum; } public boolean hasNext(){ //迭代器的hasNext方法其实是委托给枚举的hasMoreElements方法 return enum.hasMoreElements(); } public object next(){ //迭代器的next方法其实是委托给枚举的nextElement方法 return enmu.nextElement(); } public void remove(){ //很不幸,枚举不支持remove方法,所以必须放弃,在这里,我们抛出一个UnsupportedOperationException throw new UnsupportedOperationException(); }} public void publishNewsPaper() { NewsPaperOffice newPaperOffice = new NewsPaperOffice("观察者日报社"); Paper = newsPaperOffice.getPaper("《观察者日报》"); Google.send(paper); Yahoo.send(paper); Sina.send(paper);} 

List<Observer> observers;Newspaper newspaper;public NewspaperOffice(){ observers = new List<Observer>();}public void changeNewspaper(Newspaper n){ newspaper = n; notifyObservers();}public void registerObserver(Observer o){ observers.Add(o);}public void removeObserver(Observer o){ observers.Remove(o);}public void notifyObservers(){ foreach (Observer var in observers) { var.update(newspaper); }}class Chinese extends Observer{ Newspaper newspaper; Observer Members; public void update(Newspaper n) { this.newspaper = n; display(); } public void display() { System.out.println("I am a chinese and I have got the newspaper"); this.newspaper.display(); }}class Cybertron extends Observer{ Newspaper newspaper; public Newspaper translate(Newspaper n) { Newspaper tmp = n; //translate the newpaper. tmp.setContent("@#$$(@*&@&^@**@(!)!@))#(@&@$ @*#*$^*@("); return tmp; } public void update(Newspaper n) { this.newspaper = n; display(); } public void display() { System.out.println("I am a Cybertron and I have got the newspaper"); translate(newspaper).display(); }} class Sylar extends Observer{ Newspaper newspaper; Observer Members; public void update(Newspaper n) { this.newspaper = n; display(); } public void display() { System.out.println("I am Sylar and I have got the newspaper"); this.newspaper.display(); }} 

public class DataSourceManager{ public DataSource getDataSource(){ return new DataSourceImpl("dburl","user","password"); }} public class DataSourceManager { private String dbUrl; private String user; private String password; static { //读取jdbc.properties,初始化dburl,user,password } public DataSource getDataSource(){ return new DataSourceImpl(dbUrl,user,password); }}
