ZPY博客

设计模式总结之装饰模式(Decorator)

装饰模式的出现个人认为主要是为了解决继承的不足,比如有的时候我们只想给一类对象动态的加上一些行为,如果我们用小继承,就必须修改超类,但一旦修改了超类,就会导致所有继承它的类都有了这个方法,然而并不是所有类都需要。

这时装饰模式就能很好的解决问题。

装饰模式最核心的一点就是被装饰类和装饰类继承同一个超类。其实这个很好理解,一个类被装饰后还是它自己。

一个简单的例子:我们都知道汽车能跑,于是我们抽象出一个超类car有run方法,现在我有一个汽车能飞,怎么办?这时增加一个装饰类FlyCarDecorator继承car来实现fly方法。这样我们只需要让装饰类FlyCarDecorator来让汽车实现fly的功能即可。具体实现也很简单,就是装饰类的构造函数里传入需要被装饰的car对象即可。

这样设计后,如果我们需要一个汽车能swim,不需要修改之前的代码,只需要新增一个SwimCarDecorator的装饰类即可。这样就遵守了开放(易于扩展)封闭(不修改原来的代码)原则。

如果我们的汽车要既能fly又能swim呢?简单!只需要先让FlyCarDecorator装饰它,再让SwimCarDecorator装饰它就行了~~

装饰模式在实际的应用中,比如java.io包里的FilterInputStream是一个抽象装饰者,它下面的BufferedInputStream,LineNumberInputStream都是具体的装饰者,可以装饰InputStream对象。

下面是一个完整的代码例子

package com.decorator;

public abstract class Car {
    public void run(){
        System.out.println("i can run!");
    }
    public String getInfo(){
        return "i can run";
    }

    public void show() {
        this.run();
    }
}

 

package com.decorator;

public class CarDecorator extends Car {
    public Car car;

    public CarDecorator(Car car) {
        this.car = car;
    }
}

 

package com.decorator;

public class FlyCarDecorator extends CarDecorator {
    public FlyCarDecorator(Car car){
        super(car);
    }

    @Override
    public void show() {
        super.car.show();
        this.fly();
        
    }
    public  void fly() {
        System.out.println("i can fly !");
    }

    public String getInfo(){
        return car.getInfo() + ",fly";
    }
}

 

package com.decorator;

public class SwimCarDecorator extends CarDecorator {
    public SwimCarDecorator(Car car) {
        super(car);
    }

    @Override
    public void show() {
        super.car.show();
        this.swim();

    }

    public void swim() {
        System.out.println("i can swim!");
    }

    public String getInfo(){
        return car.getInfo() + ",swim";
    }
}

 

package com.decorator;

/**
 * 测试类
 */
public class DecoratorTest {
    public static void main(String[] args) {
        Car car = new RunCar();
        Car flycar = new FlyCarDecorator(car);
        flycar.show();
        System.out.println("--------------");
        Car swimflycar = new SwimCarDecorator(flycar);
        swimflycar.show();
        System.out.println(swimflycar.getInfo());
    }
}