装饰模式


装饰模式的作用

  装饰模式是对继承的一种替代方案,但比继承有更高的灵活性。

实例

  举个例子,我们对于新买的一辆车进行改装,如改装音响、贴个膜、换个轮毂等。新买的车子是我们需要改造的对象,以继承的实现方式,可以将新车子作为被继承的类,在继承的类中实现对车子的“改装”,而通常我们有多种改装,也有多种组合方式,比如我的车子只要贴膜和改音响,你的车子只要贴膜和换轮毂,这样通过继承实现起来就比较费劲,通过装饰模式可以灵活实现“多种改装”。

具体实现

  装饰模式包含4个部分:被装饰者抽象(车),具体被装饰者(奥迪车),装饰者抽象(改装车),具体装饰者(贴膜)。

代码

被装饰者抽象(车):

public interface Car
{
    public void run();
}

具体被装饰者(奥迪车)

public class Audi implements Car
{
    @Override
    public void run()
    {
        System.out.println("raw audi");
    }
}

装饰者抽象(改装车)

public class CarDecorator implements Car
{
    private Car car;
    
    public CarDecorator(Car car)
    {
        this.car = car;
    }
    
    @Override
    public void run()
    {
        car.run();
    }
    
}

具体装饰者(贴膜改装)

public class Skin extends CarDecorator
{
    public Skin(Car car)
    {
        super(car);
    }
    
    public void run()
    {
        super.run();
        System.out.println("look better");
    }
}

具体装饰者(JBL音响改装)

public class JBLSound extends CarDecorator
{
    public JBLSound(Car car)
    {
        super(car);
    }
    
    public void run()
    {
        super.run();
        System.out.println("sound better");
    }
}

执行改装

public class Test
{
    public static void main(String[] args)
    {
        Car car = new Audi();
        CarDecorator carDecorated = new JBLSound(car);
        carDecorated = new Skin(carDecorated);
        carDecorated.run();
    }
}

输出:

raw audi
sound better
look better

我们看到,经过改装后,这是一辆比原装奥迪音响更换,外观更好看的车,但注意经“改装”后的对象,本质上还是一辆车。

可以看出,通过装饰模式,我们可以动态地对原对象进行多种装饰,相比静态继承的实现方式,有更高的灵活性。