设计模式——装饰者模式

来源:互联网 发布:java定义数组的方法 编辑:程序博客网 时间:2024/06/14 02:00

    在学习设计模式的时候,发现装饰这模式和代理模式在某些地方是很相像的,那么具体又有什么区别和联系呢?让我们根据实例来看一看:


1. 装饰者模式:

    

    百度百科上说:装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

    其实装饰者模式顾名思义,就是可以给一个对象动态增加新的功能。使用装饰者模式时,需要提供一个公共的接口或抽象类。要求公共的装饰类和被装饰类实现同一个接口,并且装饰对象持有被装饰对象的实例。而所有的“装饰”都是继承自公共的装饰类的。


  装饰者模式的特点如下:

  

  (1) 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。

  (2) 装饰对象包含一个真实对象的引用(reference)

  (3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。

  (4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

    

  看文字实在是有点头疼,以下是以汽车(Car)为例子的一个装饰者模式实例:


首先创建一个Car接口
package designpatterns.decorator;/** * Created by Olive on 2017/9/11. */public interface Car {    // 给汽车加装饰    void decorate();    // 汽车的价钱    int getPrice();}
建立一个Car的实现类
package designpatterns.decorator;/** * Created by Olive on 2017/9/11. */public class CarImpl implements Car{    public void decorate() {        System.out.println("This is a car!");    }    public int getPrice() {        return 100000;    }}
建立公共的装饰者类
package designpatterns.decorator;/** * Created by Olive on 2017/9/11. */public class CarDecorator implements Car{    // 装饰对象持有被装饰对象的实例    private Car car;    public CarDecorator(Car car){        this.car = car;    }    public void decorate() {        //System.out.println("before decorate");        car.decorate();        //System.out.println("after decorate");    }    public int getPrice() {        return car.getPrice();    }}

以下为两个继承至CarDecorator的两个装饰
package designpatterns.decorator;/** * Created by Olive on 2017/9/11. */public class Sunroof extends CarDecorator{    public Sunroof(Car car){        super(car);    }    @Override    public void decorate() {        super.decorate();        System.out.println("  Now this car has a sunroof!");    }    @Override    public int getPrice() {        return super.getPrice() + 10000;    }}
package designpatterns.decorator;/** * Created by Olive on 2017/9/11. */public class Perfume extends CarDecorator{    public Perfume(Car car){        super(car);    }    @Override    public void decorate() {        super.decorate();        System.out.println("  Now this car has a bottle of perfume! And need a beauty XD~~");    }    @Override    public int getPrice() {        return super.getPrice() + 1000;    }}
然后来跑一下这个例子吧!!!
package designpatterns.decorator;/** * Created by Olive on 2017/9/11. * * 装饰器模式的应用场景: 1、需要扩展一个类的功能。 2、动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。) */public class CarDecoratorTest {    public static void main(String[] args){        Car car = new CarImpl();        System.out.println("Car's price : " + car.getPrice());        // 单纯加一个天窗吧!        Car sunroof = new Sunroof(car);        sunroof.decorate();        System.out.println("Car's price : " + sunroof.getPrice());        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");        // 单纯加一瓶香水吧!        Car perfume = new Perfume(car);        perfume.decorate();        System.out.println("Car's price : " + perfume.getPrice());        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");        // 在有天窗的车上多加一瓶香水!        Car bothAdd = new Perfume(sunroof);        bothAdd.decorate();        System.out.println("Car's price : " + bothAdd.getPrice());    }}

结果如下:

Car's price : 100000This is a car!  Now this car has a sunroof!Car's price : 110000>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>This is a car!  Now this car has a bottle of perfume! And need a beauty XD~~Car's price : 101000>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>This is a car!  Now this car has a sunroof!  Now this car has a bottle of perfume! And need a beauty XD~~Car's price : 111000


上面实例的逻辑框图如下:



下次写下代理模式(静态代理和动态代理),然后和装饰者模式对比下~