- A+
所属分类:设计模式
装饰模式的出现个人认为主要是为了解决继承的不足,比如有的时候我们只想给一类对象动态的加上一些行为,如果我们用小继承,就必须修改超类,但一旦修改了超类,就会导致所有继承它的类都有了这个方法,然而并不是所有类都需要。
这时装饰模式就能很好的解决问题。
装饰模式最核心的一点就是被装饰类和装饰类继承同一个超类。其实这个很好理解,一个类被装饰后还是它自己。
一个简单的例子:我们都知道汽车能跑,于是我们抽象出一个超类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());
}
}
