每天一个设计模式-3 适配器模式(Adapteer)

1.现实中的情况

旧式电脑的硬盘是串口的,直接与硬盘连接,新硬盘是并口的,显然新硬盘不能直接连在电脑上,于是就有了转接线。好了,今天的学习主题出来了“适配器”。

2.联系编程

有一个电源类,一个旧的硬盘类,还有一个新硬盘类;电源类能直接适配旧硬盘类,但不能和新硬盘适配。

这时,可以添加一个适配器类,这里采用对象引用的方式实现适配器。

3.类图

模式简图:

测试时使用的类图:

UML类图讲解:http://blog.csdn.net/tianhai110/article/details/6339565

4.代码

NewDiskApi:

public interface NewDiskApi {

    public void InstallNewDisk();

}

NewDiskApi

NewDisk:

public class NewDisk implements NewDiskApi {

    public NewDisk(){

    }

    public void finalize() throws Throwable {

    }

    public void InstallNewDisk(){
        System.out.println("安装新磁盘");
    }

}

NewDisk

OldDiskApi:

public interface OldDiskApi {

    public void InstallthisDisk();

}

OldDiskApi

OldDisk:

public class OldDisk implements Computer {

    public OldDisk(){

    }

    public void finalize() throws Throwable {

    }

    public void installDisk(){
        System.out.println("安装旧磁盘");
    }

}

OldDisk

Adapter:

public class Adapter implements Computer {

    private NewDiskApi newDiskApi;

    public Adapter(NewDiskApi newDiskApi){
        this.newDiskApi = newDiskApi;
        System.out.println("因为不支持新磁盘,所以使用了"+this.getClass().getName());
    }

    public void finalize() throws Throwable {

    }

    public void installDisk(){
        newDiskApi.InstallNewDisk();
    }

}

Adapter

Client:

public class Client {

    public Client(){

    }

    public void finalize() throws Throwable {

    }
    public static void main(String[] args){
        Computer oldDisk = new OldDisk();
        oldDisk.installDisk();
        Computer newDisk = new Adapter(new NewDisk());
        newDisk.installDisk();
    }

}

Client


测试结果:

安装旧磁盘
因为不支持新磁盘,所以使用了Adapter
安装新磁盘

5.模式讲解

适配器模式的主要功能就是转换匹配,复用已有功能,但并不是说,在适配器里面就不能实现其他功能,相反,适配器里面可以将多个模块的方法组合来完成一个功能,称这种适配器为智能适配器。

适配器模式可以被实现主要是通过对象引用(Adaptee在这里指的是newDiskApi)方式使不兼容的接口兼容(通过Adapter).

还有一种适配方式是缺省适配:

为一个接口提供缺省实现。然后通过继承这个缺省对象,让子类有选择的覆盖实现需要用的方法。

注意:使用适配器模式有一个潜在的问题,就是被适配的对象(就是被Adapter适配的newDiskApi)不再兼容Adaptee的接口,因为适配器只实现了Target(在这里就是上面的Computer,如果Adapter也实现了newDiskApi就不存在这样的问题了).这导致并不是所有Adaptee对象可以被使用的地方都能使用适配器。

双向适配器:

双向适配器就是适配器类分别实现了不同的Adateee(联系例子指的就是newDisk),并通过对象引用不同的Adaptee,此时的适配器可以同时当作Target和Adapter来使用,下面使用类图来表示也许更好理解一点:

6.适配器模式的优缺点

优点:

更好的复用性:如果功能已经被实现,只是接口不兼容,可以通过适配器模式解决。更好的可扩展性:实现适配器功能时,也可以调用自己开发的功能,从而很自然的扩展系统。

缺点:

过多使用适配器模式,可能会使系统变得非常混乱,不容易整体把握。

7.总结

转换匹配,复用功能适配器里面引用的对象是实现的核心,在适配器内部调用不兼容的接口对象,屏蔽了不兼容接口对象与Target的直接交互,所以达到了适配的目的。

---------博主写博客不容易,转载注明出处,谢谢:http://www.cnblogs.com/xiemubg/p/5951159.html

添加到反广告列表

每天一个设计模式-3 适配器模式(Adapteer)的更多相关文章

  1. Head First 设计模式之适配器模式与外观模式

    Head First设计模式之适配器模式与外观模式 前言: 之前讲过装饰者模式,将对象包装起来并赋予新的职责,这一章我们也会将对象进行包装,只不过是让它们看起来不像自己而像是别的东西.这样就可以在设计 ...

  2. C#设计模式(7)——适配器模式(Adapter Pattern)

    一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将“将现存的对象”在新的环境中进行调用 ...

  3. Java(Android)编程思想笔记02:组合与继承、final、策略设计模式与适配器模式、内部类、序列化控制(注意事项)

    1.组合和继承之间的选择 组合和继承都允许在新的类中放置子对象,组合是显式的这样做,而继承则是隐式的做. 组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形.即在新类中嵌入某个对象,让其实 ...

  4. 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)

    原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...

  5. C#设计模式之七适配器模式(Adapter)【结构型】

    一.引言   从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题, ...

  6. 8.3 GOF设计模式二: 适配器模式 Adapter

    GOF设计模式二: 适配器模式 Adapter  为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式  SingleTon的三个关键点  ...

  7. C#设计模式之六适配器模式(Adapter Pattern)【结构型】

    一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题,那[ ...

  8. C#设计模式(7)——适配器模式(Adapter Pattern)(转)

    一.引言 在实际的开发过程中,由于应用环境的变化(例如使用语言的变化),我们需要的实现在新的环境中没有现存对象可以满足,但是其他环境却存在这样现存的对象.那么如果将“将现存的对象”在新的环境中进行调用 ...

  9. 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)

    怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...

随机推荐

  1. 如何为你的微信小程序体积瘦身?

    众所周知,微信小程序在发布的时候,对提交的代码有1M大小的限制!所以,如果你正在写一个功能稍微复杂一点的小程序,就必须得时刻小心注意你的代码是不是快触及这个底线了. 在设计一个小程序之初,我们就需要重 ...

  2. Unicode 和 UTF-8 有何区别?

    Unicode符号范围 (一个字符两个字节)     | UTF-8编码方式 (十六进制)     | (二进制) —————————————————————– 这儿有四个字节从-----00 00 ...

  3. iOS之开发中常用的颜色及其对应的RGB值

      R G B 值   R G B 值   R G B 值 黑色 0 0 0 #000000 黄色 255 255 0 #FFFF00 浅灰蓝色 176 224 230 #B0E0E6 象牙黑 41 ...

  4. grunt配置任务

    这个指南解释了如何使用 Gruntfile 来为你的项目配置task.如果你还不知道 Gruntfile 是什么,请先阅读 快速入门 指南并看看这个Gruntfile 实例. Grunt配置 Grun ...

  5. Linux 桌面系统字体配置要略

    字体显示效果测试 这一段是为了测试宋体字的显示效果,包括宋体里面自带的英文字体,“This is english,how does it look like?”.这一行是小字.后面几个字是加粗的宋体. ...

  6. HTML5笔记:跨域通讯、多线程、本地存储和多图片上传技术

    最近做项目在前端我使用了很多新技术,这些技术有bootstrap.angularjs,不过最让我兴奋的还是使用了HTML5的技术,今天我想总结一些HTML5的技术,好记性不如烂笔头,写写文章可以很好的 ...

  7. 曲演杂坛--蛋疼的ROW_NUMBER函数

    使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...

  8. python的赋值

    python的赋值其实就是引用,我们用python的id函数看一下: 然而令人蛋疼的事情发生了, 为什么会给一个新的c赋值1,它与上面的a和b的id一样呢. 原来是python会认为一些小的整形会经常 ...

  9. FireFox调试手机浏览器

    https://developer.mozilla.org/en-US/docs/Tools/Remote_Debugging/Firefox_for_Android IN THIS ARTICLE ...

  10. python处理命令行参数

    直接从命令行执行py文件的时候如果带有参数,如何获取这些参数,如何解析? http://blog.chinaunix.net/uid-20786165-id-3182268.html sys.argv ...