• 设计模式---装饰器模式


    简述

    运行时,为原对象拓展新的行为。

    相较于传统的继承来拓展新的行为,装饰器模式更为的灵活多变,当然实现起来也更为复杂。

    话不多说,看个优化案例吧。

    优化案例

    最初版v0

    现有系统中有设定窗口Style的模块,现在想增加一个圆角的样式。以下是现有模块的代码。

    class Style {    public void style() {
            System.out.println("设置Order");
        }}
    
    • 1
    • 2
    • 3

    第一种传统的修改方式。

    class Style {
        public void style() {
            System.out.println("设置Order");
            System.out.println("设置Radius");
        }}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    虽然代码简单,但细想一下,如果我们日后仍然需要单独设置Order的样式怎么办。现在的代码实现已经无法满足了不是?

    为此,我们可能会想到另一种方案。使用继承。

    class BaseStyle {
        public void style() {
            System.out.println("设置Order");
        }}class Radius extends BaseStyle {
        public void style() {
            super.style();
            System.out.println("设置Radius");
        }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    确实,如果不在意类的命名的话,目前来看这确实是个好的选择。请注意,只是目前来看。设计不只着眼与当前,而是需要放眼未来。什么意思呢?比如,当未来需要添加一个Color样式的时候怎么办,有人可能认为添加再添加一个BassStyle类的子类Color就好了;如果客户就只要一个单独的Color样式呢,或者说需要一个可以设置Radius和Color的样式。再超前一些,客户如果想要的是增加一个样式,且可以与现有的任何一种或多种样式随意组合呢?又该怎么办?传统的继承已经搞不了了呀。

    别慌,最后这一种需求正好就是使用装饰器模式的目的。我们来看看改进后的案例吧。

    修改版v1

    使用装饰器模式优化上述需求,使得任意样式间可以任意组合,这种任意组合包括任意种类和数量。

    public interface Style {
        void style();}public class Order implements Style {
        @Override    public void style() {
            System.out.println("设置Order");
        }}
    public class Radius implements Style {
        @Override    public void style() {
            System.out.println("设置Radius");
        }}
     public class Color implements Style {
        @Override
        public void style() {
            System.out.println("设置Color");
        }}public class OrderDecorator implements Style {
        private Style style;
        public OrderDecorator(Style target) {
            this.style = target;
        }
        @Override
        public void style() {
            style.style();
            decorator();
        }
        private void decorator() {
            System.out.println("设置Order");
        }}
    public class RadiusDecorator implements Style {
        private Style style;
        public RadiusDecorator(Style target) {
            this.style = target;
        }
        @Override
        public void style() {
            style.style();
            decorator();
        }
        private void decorator() {
            System.out.println("设置Radius");
        }}
    public class ColorDecorator implements Style {
        private Style style;
        public ColorDecorator(Style target) {
            this.style = target;
        }
        @Override
        public void style() {
            style.style();
            decorator();
        }
        private void decorator() {
            System.out.println("设置Color");
        }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    定义三个装饰器类:OrderDecoratorRadiusDecoratorColorDecorator分别实现Style接口,定义decorator方法用(动态拓展的核心方法之一)。调用完``targetstyle方法后调用decorator`方法实现功能的动态拓展。接着,看看客户端如何使用。

    public class Client {
        public static void main(String[] args) {
            Style style = new Order();
            Style style1 = new ColorDecorator(style);
            Style style2 = new RadiusDecorator(style1);
            style2.style();
        }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出结果:

    设置Order设置Color设置Radius
    
    • 1

    修改版v2

    上述优化可以看到一些重复冗余的代码,还有再次优化的空间。以下是实现样例。

    public interface Style {
        void style();}public class Order implements Style {
        @Override
        public void style() {
            System.out.println("设置Order");
        }}
    public class Radius implements Style {
       @Override    public void style() {
            System.out.println("设置Radius");
        }}
    public class Color implements Style {
        @Override
        public void style() {
            System.out.println("设置Color");
        }}
    public abstract class StyleDecorator implements Style {
     // 抽出共通新建装饰类的高层抽象类
        protected Style style;
        public StyleDecorator(Style target) {
            this.style = target;
        }
        @Override
        public void style() {
     // style设置
            style.style();
            decorator();
        }
        protected abstract void decorator();
     // 装饰方法
        }
    public class OrderDecorator extends StyleDecorator {
        public OrderDecorator(Style target) {
            super(target);
        }
        @Override
        protected void decorator() {
            System.out.println("设置Order");
        }}
    public class RadiusDecorator extends StyleDecorator {
        public RadiusDecorator(Style target) {
            super(target);
        }
        @Override
        protected void decorator() {
            System.out.println("设置Radius");
        }}public class ColorDecorator extends StyleDecorator {
        public ColorDecorator(Style target) {
            super(target);
        }
        @Override
        protected void decorator() {
            System.out.println("设置Color");
        }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    客户端的使用和输出结果还是和v1一样。

    public class Client {
        public static void main(String[] args) {
            Style style = new Order();
            Style style1 = new ColorDecorator(style);
            Style style2 = new RadiusDecorator(style1);
            style2.style();
        }}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出结果:

    设置Order设置Color设置Radius
    
    • 1

    新建高层抽象类,讲冗余的方法属性都打包到抽象类中,减少重复的代码。
    这个应该属于题外话了,可以见得设计模式的实现方式是多种多样的。不要过度拘泥于模板。只要能达成目的,想怎么设计就可以怎么设计。

    修改版v1和v2都是装饰器模式,实际开发根据需求斟酌即可。

    总结

    优点

    1. 开发时可以自由组合各种各样的功能。
    2. 新增的功能对于现有功能没有任何的影响。

    缺点

    1. 增加系统的复杂度。
    2. 对于开发人员的技术要求提高。

    应用场景

    1. 需要灵活组合功能的场合。
    2. 限制继承,但又想拓展类的功能的场合。
  • 相关阅读:
    GBase 8c管理平台——4.数据迁移平台GBase 8c DMT
    Wireshark不同报文颜色的含义
    spring DisposableBean作用,在spring Bean销毁时的钩子 以及@PreDestroy
    R语言随机波动模型SV:马尔可夫蒙特卡罗法MCMC、正则化广义矩估计和准最大似然估计上证指数收益时间序列...
    国家高新技术企业认定知识产权这样拿高分
    Spring Boot + Netty + WebSocket 实现消息推送
    信创平台:查询CPU,内存等命令
    STM32-程序占用内存大小计算
    LeetCode //C - 105. Construct Binary Tree from Preorder and Inorder Traversal
    3.蓝牙模块HC-08
  • 原文地址:https://blog.csdn.net/Huangjiazhen711/article/details/127746392