装饰器模式

122 阅读2分钟

今天聊聊装饰器模式(Decorator Pattern)。

目的

在不改变原有代码的前提下为原来的方法增加新的能力。

例子代码

我今天在朋友圈突然发现了大家会分享自己的 "剪映" 的图片,不出所料,又是字节跳动的 APP, 只要是娱乐方向 APP, 只有你想不到, 没有字节跳动没做的。

8 周年一鸣又要提高员工的幸福度又要进军教育了,“让天下没有难办的教育” 马上就要成为目标了......

我大概看了看视频,剪映大概是个视频剪辑或渲染工具,最近很火的好像是个 “手拿花花”,大概是这个样子:

所以呢, 这种类似于视频或者图片的修剪,确实是装饰器模式最好的例子,我们以图片为例,可以先假设普通的方法来实现这个功能, 那么大概是这样:

//用户先放了一个手Hand hand = new Hand();//用户创建了绿叶HandWithLeaf handWithLeaf = new HandWithLeaf();handWithLeaf.setHand(hand);//用户创建完绿叶又创建了花HandWithLeafAndFlower = new HandWithLeafAndFlower();............

问题分析

上面代码的问题显而易见。一个是类太多了, HandWithLeafAndFlower 是个类,如果用户先放花后放绿叶 那HandWithFlowerAndFlower 又是一个类了。

装饰器模式

我们先定义一个接口来代表展示图片:

public interface Component {    String showPicture();}

再来定义一个基础类, 就是手:

public class Hand implements Component {    @Override    public String showPicture() {        return "展示纤纤玉手";    }}

定义一个装饰器的基类:

public abstract class Decorator implements Component {        protected Component component;    public Decorator(Component component) {        this.component = component;    }}

定义几个装饰器:

花装饰器:

public class FlowDecorator extends Decorator {    public FlowDecorator(Component component) {        super(component);    }    @Override    public String showPicture() {        return component.showPicture() + "加上鲜花";    }}

叶子装饰器:

public class LeafDecorator extends Decorator {    public LeafDecorator(Component component) {        super(component);    }    @Override    public String showPicture() {        return component.showPicture() + "加上绿色叶子";    }}

音乐装饰器:

public class MusicDecorator extends Decorator {    public MusicDecorator(Component component) {        super(component);    }    @Override    public String showPicture() {        return component.showPicture() + "加上播放音乐";    }}

然后看下效果:

public class App {    public static void main(String[] args) {        Component hand = new Hand();        System.out.println(new MusicDecorator(new LeafDecorator(new FlowDecorator(hand))).showPicture());    }}

输出:

展示纤纤玉手加上鲜花加上绿色叶子加上播放音乐

类图:

课后作业

1. 如果我们需要定义一个银行首页,本来的对象叫做 indexVo,如果是新手要在右上方展示新手图片,如果是逾期用户要把背景色变红, 如果是 VIP 用户要播放音乐, 请使用装饰器模式实现

2. 有几种优惠卷,一种是打 5 折,一种是减免 20 元,一种是消费满 40 减 5 元,满 100 减 15 元,这三种优惠卷的优先级就是如题目所述,用户可能都勾选,但是可能只能用到其中一二张,给出用户总的消费金额,返回用户真实要支付的金额

微信: