每天一个设计模式-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. Sass之坑Compass编译报错

    前段时间在使用Compass时遇到了其为难处理的一个坑,现记录到博客希望能帮助到各位. 一.问题: 利用Koala或者是gulp编译提示如下,截图为koala编译提示错误: 二.解决办法 从问题截图上 ...

  2. JavaScript对象和数组

    1.JavaScript中有两个非常重要的数据类型是对象和数组. 通过"."或者"[]"来访问对象属性 举例:var book = { topic:" ...

  3. RunLoop 总结:RunLoop的应用场景(一)

    参考资料 好的书籍都是值得反复看的,那好的文章,好的资料也值得我们反复看.我们在不同的阶段来相同的文章或资料或书籍都能有不同的收获,那它就是好文章,好书籍,好资料.关于iOS 中的RunLoop资料非 ...

  4. Matrix4x4矩阵变换、欧拉角转四元数、角度转弧度

    Matrix4x4 // 重置矩阵 ][]) { m[][] = ; m[][] = ; m[][] = ; m[][] = ; m[][] = ; m[][] = ; m[][] = ; m[][] ...

  5. 在Linux(Ubuntu/openSUSE/CentOS)下配置ASP.NET(Apache + Mono)

    [题外话] 闲的无聊竟然想尝试测试自己做的项目在不同操作系统上的性能表现,所以决定试试在Linux上部署Apache和Mono的环境.由于平时很少接触Linux,所以从网上找了几篇文章(附在相关链接中 ...

  6. linux下mono,powershell安装教程

    1简介 简单来说pash就是bash+powershell 2官网 https://github.com/Pash-Project/Pash 3下载fedora20---lxde桌面---32位版. ...

  7. .Net中的AOP系列之《方法执行前后——边界切面》

    返回<.Net中的AOP>系列学习总目录 本篇目录 边界切面 PostSharp方法边界 方法边界 VS 方法拦截 ASP.NET HttpModule边界 真实案例--检查是否为移动端用 ...

  8. Storm构建分布式实时处理应用初探

    最近利用闲暇时间,又重新研读了一下Storm.认真对比了一下Hadoop,前者更擅长的是,实时流式数据处理,后者更擅长的是基于HDFS,通过MapReduce方式的离线数据分析计算.对于Hadoop, ...

  9. 使用mapreduce计算环比的实例

    最近做了一个小的mapreduce程序,主要目的是计算环比值最高的前5名,本来打算使用spark计算,可是本人目前spark还只是简单看了下,因此就先改用mapreduce计算了,今天和大家分享下这个 ...

  10. ActiveMQ的集群方案对比及部署

    转载:http://blog.csdn.net/lifetragedy/article/details/51869032 ActiveMQ的集群 内嵌代理所引发的问题: 消息过载 管理混乱 如何解决这 ...