Java设计模式之装饰者模式

1. 什么是装饰者模式

装饰者模式就是动态的给某个对象扩展一些额外的功能。装饰模式相比生成子类更为灵活。

2. 装饰者模式中都有什么角色

2.1. 抽象组件(Component)

给出一个抽象接口,用来规范准备接收附加功能的对象

2.2. 具体组件(ConcreteComponent)

将要被附加功能的类,实现抽象组件角色的接口

2.3. 抽象装饰者组件(Decorator)

是抽象组件的一个子类,是“装饰者”角色,其作用是装饰具体组件,因此,抽象装饰者角色需要包含抽象组件的引用。可以是抽象类,也可以是非抽象类。

2.4. 具体装饰者组件(ConcreteDecorator)

实现抽象装饰者角色,负责对具体组件添加额外功能

3. 类图

image

4. 代码描述

装饰模式是动态的扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。

在许多设计中,可能需要改进对某个对象的功能,而不是该类所有的对象。

  • 例如:小鸟类的实例对象可以连续飞行100米,我们创建了5只小鸟,想让其中一只可以连续飞行200米,其他鸟还是100米。
  • 这时我们可以给这只小鸟装一个加速器,这只小鸟就可以借助加速器比别的小鸟多飞100米,如果装两个加速器,小鸟就可以飞300米。
  • 这就是我们设计装饰者模式的初衷——改变类的某个对象的功能

4.1. 抽象组件

public abstract class Bird {
    public abstract int fly();
}

4.2. 具体组件

具体组件是抽象组件的一个子类,具体组件的实例称为“被装饰者”。

public class SuperBird extends Bird {
    public final int DISTANCE = 100;

    @Override
    public int fly() {
        return DISTANCE;
    }
}

4.3. 抽象装饰者组件

抽象装饰组件是抽象组件的一个子类,其作用是装饰具体组件。因此,抽象装饰组件需要包含“被装饰者”的引用。而且,抽象装饰组件本身也是抽象组件的子类,即也是具体组件的角色,不同之处在于,抽象装饰组件额外提供了一些方法。

public abstract class Faster extends Bird {
    Bird bird;//被装饰者

    public Faster(Bird bird) {
        this.bird = bird;
    }

    @Override
    public int fly() {
        return bird.fly();
    }

    public abstract int eleFly();//用于修饰fly()方法,具体行为由装饰者去实现
}

4.4. 具体装饰组件

根据具体的问题,具体装饰组件用新的方法去装饰具体组件。

public class FasterDecorator extends Faster {
    public final int ELEDISTANCE = 100;//加速器能多飞100米

    FasterDecorator(Bird bird) {
        super(bird);
    }

    @Override
    /**
     * 被装饰的方法
     */
    public int fly() {
        return bird.fly() + eleFly();
    }

    @Override
    /**
     *具体装饰者重写装饰者中用于装饰的方法
     */
    public int eleFly() {
        return ELEDISTANCE;
    }
}

4.5. 测试

public class Test {
    public static void main(String[] args) {
        Bird bird=new SuperBird() ;
        System.out.println("没有安装加速器的小鸟飞行距离:"+bird.fly());
        bird=new FasterDecorator(bird);
        System.out.println("安装了1个加速器的小鸟飞行距离:"+bird.fly());
        bird=new FasterDecorator(bird);
        System.out.println("安装了2个加速器的小鸟飞行距离:"+bird.fly());
        bird=new FasterDecorator(bird);
        System.out.println("安装了3个加速器的小鸟飞行距离:"+bird.fly());

    }
}

运行结果

没有安装加速器的小鸟飞行距离:100
安装了1个加速器的小鸟飞行距离:200
安装了2个加速器的小鸟飞行距离:300
安装了3个加速器的小鸟飞行距离:400

5. 使用多个装饰器

由于抽象装饰组件本身也是抽象组件的一个子类,所以“装饰者”本身也可以成为一个“被装饰者”,这意味着我们可以使用多个具体装饰类来装饰具体组件的实例。

  • 比如我们需要一个可以飞行150米的鸟,那么就不必修改现有的类,只需要再添加一个具体装饰即可。
public class FasterDecorator2 extends Faster{
    public final int ELEDISTANCE = 50;//加速器能多飞50米

    FasterDecorator2(Bird bird) {
        super(bird);
    }

    @Override
    /**
     * 被装饰的方法
     */
    public int fly() {
        return bird.fly() + eleFly();
    }

    @Override
    /**
     *具体装饰者重写装饰者中用于装饰的方法
     */
    public int eleFly() {
        return ELEDISTANCE;
    }
}
Bird bird=new SuperBird() ;
bird=new FasterDecorator(bird);
bird=new FasterDecorator(bird);
bird=new FasterDecorator(bird);
bird=new FasterDecorator2(bird);

6. 装饰模式的优势

  • 被装饰者和装饰者是松耦合关系,由于抽象装饰组件仅仅依赖于抽象组件,因此,具体装饰只需要知道它要装饰的对象是抽象组件的某一个实例,不需要知道是哪一个具体子类。

  • 装饰模式满足“开-闭”原则,用户不必修改具体组件,就可以增加新的针对该具体组件的具体装饰。

  • 可以使用多个具体装饰来装饰具体组件的实例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值