设计模式:(装饰模式)

1.定义

装饰模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
简单来说:装饰模式式动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式

2.概述

在许多设计中,可能需要改进类的某个对象的功能,而不是该类创建的全部对象。 例如,鸟类的实例(麻雀)能连续飞行100米,如果用鸟类创建了5只麻雀对象,那么这5只麻雀都能连续飞行100米。假设我们想让其中一只麻雀能够连续飞行150米(大于100),那么应当怎么做呢?我们不想通过修改麻雀类的代码使得麻雀类创建的麻雀都能连续飞行150米,这也不符合我们的初衷:改进类的某个对象的功能。
在这里插入图片描述

一种比较好的方式就是给某只麻雀装上只能电子翅膀。智能电子翅膀可以死的麻雀不适用自己的翅膀就能飞行50米。那么一只安装了这种智能电子翅膀的麻雀就能飞行150了,因为麻雀首先使用自己的翅膀飞行100米,然后在使用智能电子翅膀飞行50米,一共150米。
在这里插入图片描述

3.应用场景

1、扩展一个类的功能。
2、动态增加功能,动态撤销。

4.模式的结构和使用

装饰模式的结构中包括四种角色:
1.抽象组件(Component):抽象组件是一个抽象类。抽象组件定义了“被装饰者”需要进行“装饰”的方法;
2.具体组件(ConcreteComponent):具体组件是抽象组件的一个子类,具体组件的实例称之为“被装饰者”;
3.装饰(Decorator):装饰也是抽象组件的一个子类,但但装饰还包含一个抽象组件声明的变量以保存“被装饰者”的引用。装饰可以是抽象类也可以是一个非抽象类,如果是非抽象类,那么该类的实例就是“装饰者”;
4.具体装饰(ConcreteDecorator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称作装饰者。

1.装饰模式的UML类图

前面概述所提到的麻雀就是类图中的ConcreteComponent角色的实例,安装了一对智能电子翅膀的麻雀是ConcreteDecorator角色的实例。
在这里插入图片描述

2.结构的描述

假设系统中有一个Bird抽象类以及Bird类的一个子类:Sparrow。Sparrow类实现了Bird类的fly方法,使得Sparrow类创建的对象(麻雀)调用fly方法能连续飞行100米;
现在,用户需要两只鸟,无论那只鸟都可以,但必须分别能够连续飞行150米和200米。显然,现有的系统无法向两只用户提供这样的Bird对象,所以需要修改现有的系统。我们发现,如果使用装饰模式,不必修改原来的代码,只需要在系统中添加“装饰”,该系统将可以创建出用户需要的鸟。具体设计如下所示:
1.抽象组件
在抽象组件中定义了抽象的fly(飞行)方法;
Bird.java

package com.xing.decorator;

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

2.具体组件
定义具体组件Sparrow,在里面继承抽象组件Bird类,并实现fly方法;
Sparrow.java

package com.xing.decorator;
public class Sparrow extends Bird{
    public final int DISTANCE=100;
    @Override
    public int fly() {
        return DISTANCE;
    }
}

3.装饰
装饰类同样是抽象类,并且继承Bird,在里面实现默认构造函数和有参构造函数,并且有Bird类的引用
Decorator.java

package com.xing.decorator;
public abstract class Decorator extends Bird{
    protected Bird bird;
    public Decorator() {
    }
    public Decorator(Bird bird) {
        this.bird = bird;
    }
}

4.具体装饰
根据具体的问题,具体装饰经常委托被装饰者调用相应的方法;

package com.xing.decorator;

public class SparrowDecorator extends Decorator{
    public final int DISTANCE=50;
    public SparrowDecorator(Bird bird) {
        super(bird);
    }

    @Override
    public int fly() {
        int distance=0;
        distance=bird.fly()+eleFly();//委托被装饰者bird调用fly方法,然后在调用eleFly()
        return distance;
    }
    private int eleFly(){
        return DISTANCE;//eleFly方法能够飞50米
    }
}

5.主程序测试

package com.xing.decorator;
public class Application {
    public void needBird(Bird bird){
        System.out.println("这只鸟能够飞行"+bird.fly()+"米");
    }
    public static void main(String[] args) {
        Application application=new Application();
        Bird sparrow=new Sparrow();//sparrow能够飞行100米
        Bird sparrowDecorator1=new SparrowDecorator(sparrow);//sparrowDecorator1能飞行100+50米
        Bird sparrowDecorator2=new SparrowDecorator(sparrowDecorator1);sparrowDecorator1能飞行150+50米
        application.needBird(sparrowDecorator1);
        application.needBird(sparrowDecorator2);
    }
}

6.测试结果展示
在这里插入图片描述

5.装饰模式的优点

1.被装饰者和装饰者是松耦合关系。
2.装饰模式满足开闭原则
3.可以使用多个具体装饰来装饰具体组件的实例。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

散一世繁华,颠半世琉璃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值