设计模式之适配器模式

来源:互联网 发布:无线访客网络设置 编辑:程序博客网 时间:2024/05/17 07:04

之前几篇文章都是讲的创建型的设计模式,今天则开始讲解结构型设计模式。首先今天要学习的是适配器模式。

我们可能会遇到这样的情形:要通过手机直接复制U盘里面的文件,可目前的手机根本无法直接连接U盘,因为U盘一般是USB2.0或者3.0型的接口,没办法直接插到我们的手机上,这个时候我们就需要通过中间器件来实现了,即买一根OTG的连接线就可以了。从这个例子中我们知道,手机需要的是一个Type-C接口(不同手机不一样,有的是Micro USB接口),而目前我们只有一个USB2.0接口的U盘,因此我们需要一个适配器即OTG线来从中间连接它们。那么在Java开发中,我们将此称之为适配器模式。接下来笔者就以这个例子来讲解适配器模式。

适配器模式分四个重要的组件:

①:Target(目标接口),即客户端需要的接口类型,可以是具体的类或者接口类型。相当于我们例子中的手机需要的Type-C接口;

②:Adaptee(被适配的对象),相当于例子中U盘的USB2.0接口(需要被匹配到的手里上);

③:Adapter(适配器),起连接客户端和被适配对象的作用,相当于例子中的OTG线。

④:客户端(Client),相当于例子中的手机。

我们碰到的情形是:


这时候我们就需要一个适配器Adapter了,先看看UML图:


我们听过Adapter来连接两者,即通过OTG线来连接手机和U盘,下面用代码来具体实现:

代码中定义了一个Client类(手机),类中有一个方法,用来模拟从手机中读取U盘中的文件;一个Target接口(手机需要的接口类型)接口中有一个方法,用来模拟处理手机要读取U盘数据的请求;一个Adaper类(即OTG线),该类实现了Target接口,并具体实现了接口中的方法,而且该类中持有Adaptee类的引用;一个Adaptee类(即U盘),类中有一个方法,用来模拟返回U盘中的文件

具体代码:

package com.tiantang.adapter;/** * 客户端(相当于例子中的手机) * @author LiuJinkun * */public class Client {/** * 模拟手机从U盘中读取数据的方法 * @param target 客户端需要的类型(手机只能使用OTG线,所以需要一根OTG线) */public void getMessage(Target target){target.handle();}public static void main(String[] args) {Client c=new Client();//创建一个被适配的对象(即U盘)Adaptee adaptee=new Adaptee();//创建一个适配器(即OTG线)Target target=new Adapter(adaptee);//OTG线才是手机能使用的对象c.getMessage(target);}}
package com.tiantang.adapter;/** * 目标对象,客户端需要的类型(相当于例子中:手机不能直接连接U盘,而真正需要的是一根OTG数据线,) * @author LiuJinkun * */public interface Target {void handle();}
package com.tiantang.adapter;/** * 适配器(相当于例子中的OTG数据线) * @author LiuJinkun * */public class Adapter implements Target{private Adaptee adaptee;public Adapter(Adaptee adaptee){this.adaptee=adaptee;}@Overridepublic void handle() {adaptee.getMessage();}}
package com.tiantang.adapter;/** * 被适配的类(相当于例子中的U盘) * @author LiuJinkun * */public class Adaptee {public void getMessage(){System.out.println("显示U盘中的数据");}}

这样就实现了适配器模式,这种实现方式称之为组合对象实现(即类对象方式),通俗地可以理解成:Adapter类中持有一个Adaptee的引用,因此称之为组合对象式。还用一种实现适配器模式的方式:类继承方式,即让Adapter继承Adaptee类,这样在Adapter类中就可以直接调用Adaptee中的方法了,不过这种方式一般不建议使用,因为Java是单继承的,如果Adapter继承了Adaptee类,那么在实际开发中,当我们还需要继承其他的类的时候,这种方式就不适宜了。为了不让读者疑惑,还是把类继承方式的部分代码写到下面:

package com.tiantang.adapter;/** * 适配器(相当于例子中的OTG数据线) * @author LiuJinkun * */public class Adapter2 extends Adaptee implements Target{@Overridepublic void handle() {getMessage();}}


注意:这种类继承方式实现适配器模式不建议使用!!

在现实生活中我们会经常碰到这种适配器模式,例如插头,墙上有一个二孔的插口,而我们需要插三孔的插头,这时候就需要买一个转换的器件;例如无线鼠标与电脑的连接等等。而在程序开发中,我们也经常会看到适配器模式,例如Java中的IO流操作,InputStreamReader就是一个适配器,用来实现字节流和字符流的转换,相对应的还有OutputStreamWriter。


1 0
原创粉丝点击