包装模式

原创 2016年05月30日 15:08:03

适配器模式与装饰模式统称为包装模式。

适配器模式

①用途

适配器模式的功能就是把一个类的接口变成客户端能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作。

②适配器模式结构

这里写图片描述
图中各个角色说明如下:

  • Target(目标接口):所要转换的所期待的接口。
  • Adaptee(源角色):需要适配的接口。
  • Adapter(适配器):将源接口适配成目标接口,继承源接口(或持有源接的一个引用),实现目标类。

③Java I/O中的适配器模式

适配器的作用就是将一个接口适配到另一个接口,在Java的I/O类库中有很多这样的需求,如将字符串数据转变成字节数据保存到文件中,将字节数据转变成流数据等。
我们知道,Java I/O中InputStreamReader和OutputStreamWriter两个类是字符流和字节流转换的桥梁。InputStreamReader和OutputStreamWriter类分别继承了Reader和Writer接口,但是要创建它们的对象必须在构造函数中传入一个InputStream和OutputStream的实例。InputStreamReader和OutputStreamWriter的作用也就是将InputStream和OutputStream适配到Reader和Writer。InputStreamReader的类结构图如下:
这里写图片描述
InputStreamReader实现了Reader接口,并且持有了InputStream的引用,这里是通过StreamDecoder类间接持有的,因为从byte到char需要经过编码。
很显然,适配器就是InputStreamReader类,源角色就是InputStream代表的实例对象,目标接口就是Reader类。OutputStreamWriter类也是类似的方式。
在I/O类库中还有很多类似的用法,如StringReader将一个String类适配到Reader接口,ByteArrayInputStream适配器将byte数组适配到InputStream流处理接口。

④适配器模式示例

源角色代码:

public class Person {  

    private String name;  
    private String sex;  
    private int age;  

    public void speakJapanese(){  
        System.out.println("I can speak Japanese!");  
    }  

    public void speakEnglish(){  
        System.out.println("I can speak English!");  
    }  
    ...//以下省略成员变量的get和set方法  
}  

目标接口代码:

public interface Job {  

    public abstract void speakJapanese();  
    public abstract void speakEnglish();  
    public abstract void speakFrench();  

}  

适配器的代码:

public class Adapter extends Person implements Job{  

    public void speakFrench() {  

    }  

}  

很显然的,Adapter类继承了Person类,而在Java这种单继承的语言中也就意味着,他不可能再去继承其他的类了,这样也就是这个适配器只为Person这一个类服务。所以称其为类适配模式。
而对象适配器模式是把“源”作为一个对象聚合到适配器类中。
适配器代码:

public class Adapter implements Job {  

    Person person;  

    public Adapter(Person person) {  
        this.person = person;  
    }  

    public void speakEnglish() {  
        person.speakEnglish();  
    }  

    public void speakJapanese() {  
        person.speakJapanese();  
    }  

    //new add  
    public void speakFrench() {  

    }  

}  

类的适配模式用于单一源的适配,由于它的源的单一话,代码实现不用写选择逻辑,很清晰;而对象的适配模式则可用于多源的适配,弥补了类适配模式的不足,使得原本用类适配模式需要写很多适配器的情况不复存在,弱点是,由于源的数目可以较多,所以具体的实现条件选择分支比较多,不太清晰。

装饰模式

①用途

装饰模式就是将某个类重新包装一下,使它比原来更“漂亮”,或者在功能上更强大,但是原来的这个类的使用者不应该感受到这个被装饰前后有什么不同,装饰模式是继承关系的一个替代方案。

②装饰模式结构

这里写图片描述
图中各个角色说明如下:

  • Component:抽象组件角色,定义一个组抽象的接口,规定这个被装饰注解都有哪些功能。
  • ConcreteComponent:实现这个抽象组件的所有功能。
  • Decorator:装饰器角色,它持有一个Component对象实例的引用,定义一个与抽象组件一致的接口。
  • ConcreteDecorator:具体的装饰器实现这者,负责实现装饰器角色定义的功能。

③Java I/O中的装饰器模式

在Java I/O类库中有很多不同的功能组合情况,这些不同的功能组合都是使用装饰模式实现的,下面以FilterInputStream为例介绍装饰模式的使用。
FilterInputStream的类结构图:
这里写图片描述
InputStream类就是以抽象组件存在的,而FilterInputStream就是具体组件,它实现了抽象组件的所有接口,FilterInputStream类无疑就是装饰器角色,它实现了InputStream类的所有接口,并且持有InputStream的对象实例的引用,BufferedInputStream是具体的装饰器实现者,它给InputStream类附加了功能,这个装饰器类的作用就是使得InputStream读取的数据保证在内存中,而提高读取的性能。

④适配器模式示例

public interface Person {
    void doCoding();
}
public class Employee implements Person {

    @Override
    public void doCoding() {
        System.out.println("程序员加班写程序啊,写程序,终于写完了。。。");
    }
}
public abstract class Manager implements Person{     
    //装饰器增加功能
    public abstract void doCoding();
}
public class ManagerA extends Manager {
    private Person person;//给雇员升职

    public ManagerA(Person person) {
        super();
        this.person = person;
    }
    @Override
    public void doCoding() {
        doEarlyWork();
        person.doCoding();        
    }
    /**
     * 项目经理开始前期准备工作
     */
    public void doEarlyWork() {
        System.out.println("项目经理A做需求分析");
        System.out.println("项目经理A做架构设计");
        System.out.println("项目经理A做详细设计"); 
    }
}
public class ManagerB extends Manager {
     private Person person;//给雇员升职

     public ManagerB(Person person) {
         super();
         this.person = person;
     }
     @Override
     public void doCoding() {
         person.doCoding();
         doEndWork();
     }
     /**
      * 项目经理开始项目收尾工作
      */
    public void doEndWork() {
        System.out.println("项目经理B 在做收尾工作");
     }

}

适配器模式与装饰模式的区别

装饰器与适配器模式都有一个别名就是包装模式(Wrapper),它们看似都是起到包装一个类或对象的作用,但是使用它们的目的很不一样。适配器模式的意义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的;而装饰模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方法而提升性能,所以这两个模式设计的目的是不同的。

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

一个通用纯C队列的实现

队列并不是很复杂的数据结构,但是非常实用,这里实现一个队列是为了

设计模式之(九)--包装模式(decorator)

《设计模式》一书对Decorator是这样描述的: 动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式比生成子类更为灵活。也就是说:动态地给对象添加一些额外的功能。它的工作原理...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

装饰模式(Decorator)(包装器模式(Wrapper))

生活中的装饰是很好理解的,我们打两个比方。先还是说房子的装修,装修无非就是要在墙上刷上粉贴上壁纸挂上饰物,让房屋显得更加雅致美观。但墙还是那堵墙,本质不会改变,只是多了一层包装而已。        再...

非常精简的Linux线程池实现(一)——使用互斥锁和条件变量

其实线程池的原理非常简单,它就是一个非常典型的生产者消费者同步问题。如果不知道我说的这个XXX问题也不要紧,我下面就解释。

装饰模式(Decorator)(包装器模式(Wrapper))

生活中的装饰是很好理解的,我们打两个比方。先还是说房子的装修,装修无非就是要在墙上刷上粉贴上壁纸挂上饰物,让房屋显得更加雅致美观。但墙还是那堵墙,本质不会改变,只是多了一层包装而已。   ...

为什么开发人员工作10多年了还会迷茫?没有安全感?

眼看自己大学毕业后都快12年了,也快2个孩子的爸爸了,但是有时候还是会有不少不安全的感觉产生。都快奔35了,技术也过得去,收入其实也很稳定,但是偶尔还是会有迷茫的时候,最近有几个朋友,也发QQ聊天信息...

包装模式

适配器模式①用途适配器模式的功能就是把一个类的接口变成客户端能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作。②适配器模式结构 图中各个角色说明如下: Target(目...

装饰模式(包装模式)

装饰模式: 是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰模式是以对客户透明的方式动态的给一个对象附加上更多的责任,装饰模式可以在不增加任何子类的情况下将对象的功能加以扩展。 使...

php之大话装饰模式

这里的构造函数居然这样写。 '未命名') /* 默认值 */, $data)); } return array( 'Show' =

装饰模式

现在我们来学习装饰模式。说实话,真不想写这个,因为提到这个装饰,程序员就很伤感(我也是),就想到了遥远地她和虚无缥缈地房子。房子都还没着落,谈什么装修和粉饰啊。一堵粗糙的墙,刷上白白地粉,再贴上几张壁...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)