Adapter(适配器).ppt
Adapter(适配器)换个包装再利用,定义,引子:给手机充电,发现只支持USB接口充电方式,需要为充电器装一个接口转换器软件开发中,如果既有内容无法直接利用时,通常需要先转换成必要的类型后再使用,定义,假设网络游戏的客户端程序分两部分。一部分是和服务端通讯的大厅部分,另一部 分就是游戏程序了,由不同的公司在进行开发,通过实现约定的接口和游戏程序进行通讯。在大厅程序开发接近完成的时候,公司决定和另外一家游戏公司合作,因此希望把大厅程序能适用另一个游戏。而这个新游戏的遵循的是另一套接口。我们假设大厅程序和游戏程序之间有100个接口,是不是可以避免修改原先调用方法来启动场景呢?,定义,将一个类的接口转换成客户希望的的另外一个接口使原本由于接口不兼容而不能一起工作的那些类可以一起工作适配器模式是为了在面向接口编程中更好的复用,定义,Target:目标角色定义Client要用的特定领域的接口Adapter:适配器角色适配器模式的核心,将被适配角色已有的接口转化为目标角色希望的接口Adaptee:被适配角色有一个已经存在并使用了的接口,只个接口是需要我们适配的Client:客户调用类协同对象符合Adapter适配器(公接口),定义,定义,类型类的Adapter模式(继承)对象的Adapter模式(委托),电压转换插座,美国电器的额定电压是120V,中国电器的额定电压是220V中国和美国电器之间实现电压转换,电压转换插座,定义两个电器类的interface:ChineseAppliance和USAppliance。public interface ChineseAppliance void powerOn(ChinesePlug cp);public interface USAppliance void powerOn(USPlug up);,电压转换插座,定义两个插座类的interface:ChinesePlug和USPlug。电器接口中的powerOn方法,分别要用到ChinesePlug和USPlug对象作为参数。public interface ChinesePlug public void chargeIn220V();public interface USPlug public void chargeIn120V();,电压转换插座,ChineseAppliance接口,写一个类ChineseTV来实现。USAppliance接口,写一个USFridge类来实现。ChinesePlug接口,写一个ChinesePlugInstance类实现。USPlug接口写一个USPlugInstance类实现。,电压转换插座,public class ChineseTV implements ChineseAppliance public void powerOn(ChinesePlug cp)cp.chargeIn220V();System.out.println(ChineseTV is on);public class USFridge implements USAppliance public void powerOn(USPlug up)up.chargeIn120V();System.out.println(USFridge is on);,电压转换插座,public class ChinesePlugInstance implements ChinesePlug public void chargeIn220V()System.out.println(charge in volt 220);public class USPlugInstance implements USPlugpublic void chargeIn120V()System.out.println(charge in volt 120);,电压转换插座,创建Adapter来实现转换。ChinaToUSAdapter类实现把中国电压转换成美国电压,USToChinaAdapter类实现把美国电压转换成中国电压。,电压转换插座,public class ChinaToUSAdapter extends ChinesePlugInstance implements USPlug public void chargeIn120V()chargeIn220V();public class USToChinaAdapter extends USPlugInstance implements ChinesePlug public void chargeIn220V()chargeIn120V();,电压转换插座,AdapterTester类public class AdapterTester public static void main(Stringargs)USFridge usfridge=new USFridge();usfridge.powerOn(new ChinaToUSAdapter();ChineseTV chinesetv=new ChineseTV();chinesetv.powerOn(new USToChinaAdapter();,程序示例1(继承),把字符串输出成:String或者*String*,类、接口清单,Banner类,public class Banner private String string;public Banner(String string)this.string=string;public void showWithParen()System.out.println(“”+string+”);public void showWithAster()System.out.println(“*”+string+”*”);,Print接口,public interface Print public abstract void printWeak();public abstract void printString();,PrintBanner类,public class PrintBanner extends Banner implements Print public PrintBanner(String string)super(string);public void printWeak()showWithparen();public void printStrong()showWithAster();,PrintBanner类,继承(extends)既有的Banner类继承showWithParen,showWithAster方法实现Print接口实现printWeak,printStrong方法,Main类,public class Main public static void main(String args)Print p=newPrintBanner(“String”);p.printWeak();p.printStrong();,Main类,Main类利用print接口Main类完全看不出有Banner类,showWithParen或showWithAster方法不需要修改Main类,就能修改PrintBanner类的实现,程序示例(委托),前面的程序利用“继承”让“既有内容”符合“需要结果”委托是指把某个方法的实际处理交给其他对象的方法进行Main类,Banner类同前面的程序示例,但Print是假设为类而非接口,Print类,public abstract class Print public abstract void printWeak();public abstract void printStrong();,PrintBanner类,public class PrintBanner extends Print private Banner banner;public PrintBanner(String string)this.banner=new Banner(string);public void printWeak()banner.showWithParen();public void printStrong()banner.showWithAster();,说明,不一定每次写程序都要从零出发,经常会利用一些既有的类,Adapter模式可以把过去使用过的类重新包装建立出需要的类不必改动现有的类就能让他符合新的接口,而且不一定要取得既有类的源代码,只要知道类的规格,就能建立其他新类,说明,适配器模式强调接口转换没有源程序也无妨版本更新与兼容类的差别太大不要用冰箱变不成电视,思考,例如,在一个画图小程序中,你已经实现了绘制电、线、方块等图形的功能,而且使用了一个抽象类来规范图形的接口。现在你要实现圆的绘制,这时你发现在系统的其他地方已经有了绘制圆的实现。但是绘制圆的方法名和你在抽象类中规定的方法名不一样修改你的还是修改其他人的?有没有其他方法?适配器模式,思考,思考,思考,Shap,Circle和TextCircle三者的关系和Target,Adapter和Adaptee三者的关系相对应Class Circle extends Shape private TextCircle tc;public Circle()tc=new TextCircle();void public display()tc.displayIt();,