23种设计模式(7)-装饰者模式

来源:互联网 发布:如何用淘宝内部券赚钱 编辑:程序博客网 时间:2024/06/05 18:29

装饰模式
        一、概述
        二、装饰模式的结构
        三、具体案列
        四、装饰模式与类继承的区别
        五、装饰模式的特点:
        六、装饰模式、适配器模式、代理模式区别


一、概述

1.装饰模式(Decorator)的定义:又名包装(Wrapper)模式,装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
2.装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任。换言之客户端并不会觉的对象在装饰前和装饰后有什么区别。
3.装饰模式可以在不创造更多的子类的模式下,将对象的功能加以扩展。


二、装饰模式的结构

  装饰模式的类图如下:

这里写图片描述
  
  在装饰模式中的角色有:
  ●抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  
  ●具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
  
  ●装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
  
  ●具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

源代码

抽象构件角色

public interface Component {    public void sampleOperation();}

具体构件角色

public class ConcreteComponent implements Component {    @Override    public void sampleOperation() {        // 写相关的业务代码    }}

装饰角色

public class Decorator implements Component{    private Component component;    public Decorator(Component component){        this.component = component;    }    @Override    public void sampleOperation() {        // 委派给构件            component.sampleOperation();    }}

具体装饰角色

public class ConcreteDecoratorA extends Decorator {    public ConcreteDecoratorA(Component component) {        super(component);    }    @Override    public void sampleOperation() {     super.sampleOperation();        // 写相关的业务代码    }}
public class ConcreteDecoratorB extends Decorator {    public ConcreteDecoratorB(Component component) {        super(component);    }    @Override    public void sampleOperation() {      super.sampleOperation();        // 写相关的业务代码    }}

三、具体案列

本例中 抽象构建角色由Programmer程序员接口扮演具体构件角色由类屌丝扮演  他实现了程序员具有的功能装饰构件由 类Derector扮演 它必须也实现抽象构件接口具体装饰构件角色由 类Hacker(黑客) 和类 SoftwareAchitect(架构师)扮演具体程序员汤高有编程能力,上帝可以给他赋予更多能力 每赋予一种能力,他就多一个技能 这是通过装饰构件实现的

抽象构件角色

/** * 抽象构件角色 *  程序员接口   程序员具有编程的能力 * @author Administrator * */public interface Programmer {    //编程    public void programme();}

具体构件角色

/** * 具体构件角色   * 屌丝是一个具体的程序员   * 那么他就具有编程能力 * @author Administrator * */public class Diaosi implements Programmer {    @Override    public void programme() {        System.out.println("我是一个程序员, 我能编程");    }}

装饰角色

/** * 装饰角色 *   * @author Administrator * */public class Derector implements Programmer{    private Programmer programmer;    public Derector(Programmer programmer) {        this.programmer = programmer;    }    @Override    public void programme() {        programmer.programme();        //附加的责任或者功能    }}

具体装饰角色1

/** *  具体装饰角色   *  黑客类   他具有附加的功能  他能入侵别人的电脑 * @author Administrator * */public class Hacker extends Derector {    public Hacker(Programmer programmer) {        super(programmer);    }    @Override    public void programme() {        super.programme();        //附加的责任或者功能        System.out.println("我具有黑客的技能   我能入侵别人的电脑");    }}

具体装饰角色2

/** *  具体装饰角色   *  软件架构师类   他具有附加的功能  能设计总个网站或系统的骨 * @author Administrator * */public class SoftwareArchitect extends Derector {    public SoftwareArchitect(Programmer programmer) {        super(programmer);    }    @Override    public void programme() {        super.programme();        //附加的责任或者功能        System.out.println("我具有架构师的技能  我能设计总个网站或系统的骨架");    }}

客户端

public class Client {    public static void main(String[] args) {        //创建构件对象:屌丝 ->他是一个具体的程序员         //但是现在他只有编程能力  那怎么行        //必须赋予他更大的能力  不然怎么赚大钱!        //所以 上帝给他装饰了一番  瞬间提神了他的B格        Programmer programmer=new Diaosi();        //装饰类登场  屌丝  我来装饰你  让你具有更大的能力         Derector hacker=new Hacker(programmer);        //这下这个屌丝程序员就具有黑客的技能包了        //这下就没有谁敢叫他屌丝了吧  哈哈  不然分分钟让你电脑崩溃        System.out.println("第一次装饰");        hacker.programme();        //程序员还不满足  他还要更多的技能  因为他要逆袭        //所以上帝再给他装饰了一下         //在他具有黑客技能的基础上另外赋予了他架构师的功能        System.out.println("--------------第二次装饰");        Derector  achitect=new SoftwareArchitect(hacker);        achitect.programme();        //也可以一步装饰两个技能 因为他们有共同的父类抽象构件接口 Programmer        System.out.println("------------一步装饰两个技能");        Derector achitect1=new SoftwareArchitect(   new  Hacker(new Diaosi() ) );        achitect1.programme();    }}

结果:
第一次装饰
我是一个程序员, 我能编程
我具有黑客的技能   我能入侵别人的电脑
————–第二次装饰
我是一个程序员, 我能编程
我具有黑客的技能   我能入侵别人的电脑
我具有架构师的技能  我能设计总个网站或系统的骨架
————一步装饰两个技能
我是一个程序员, 我能编程
我具有黑客的技能   我能入侵别人的电脑
我具有架构师的技能  我能设计总个网站或系统的骨架


四、装饰模式与类继承的区别

1)装饰模式是一种动态行为,对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成什么样的,该类的对象便具有什么样的功能,无法动态的改变。

2)装饰模式扩展的是对象的功能,不需要增加类的数量,而类继承扩展是类的功能,在继承的关系中,如果我们想增加一个对象的功能,我们只能通过继承关系,在子类中增加方法。

3)装饰模式是在不改变原类文件和使用继承的情况下,动态的扩展一个对象的功能,它是通过创建一个包装对象,也就是装饰来包裹真是的对象。

五、装饰模式的特点:

1)装饰对象和真实对象具有相同的接口,这样客户端对象就可以以真实对象的相同的方式和装饰对象交互。
2)装饰对象包含一个真实对象的引用(reference).
3)装饰对象接受所有来自客户端的请求,它把这些请求转发给真实的对象。
4)装饰对象可以在转发这些请求以前或者以后增加一些附加的功能。这样就能确保在运行时,不用修改给定对象结构就可以在外部增加附加的功能。在面向对象的程序设计中,通常是使用继承的关系来扩展给定类的功能。


六、装饰模式、适配器模式、代理模式区别

适配器模式,一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

装饰器模式,原有的不能满足现有的需求,对原有的进行增强。
代理模式,同一个类而去调用另一个类的方法,不对这个方法进行直接操作。

适配器的特点在于兼容,从代码上的特点来说,适配类与原有的类具有相同的接口,并且持有新的目标对象。

就如同一个三孔转2孔的适配器一样,他有三孔的插头,可以插到三孔插座里,又有两孔的插座可以被2孔插头插入。

适配器模式是在于对原有3孔的改造。

在使用适配器模式的时候,我们必须同时持有原对象,适配对象,目标对象。。。。

装饰器模式特点在于增强,他的特点是被装饰类和所有的装饰类必须实现同一个接口,而且必须持有被装饰的对象,可以无限装饰。

代理模式的特点在于隔离,隔离调用类和被调用类的关系,通过一个代理类去调用。

总的来说就是如下三句话:
1 适配器模式是将一个类通过某种方式转换成另一个类.

3 代理模式是将一个类转换成具体的操作类.

原创粉丝点击