zoukankan      html  css  js  c++  java
  • 装饰者设计模式

    什么是装饰者设计模式

    装饰者设计模式(Decorator Pattern)将某个方法进行增强,可以在被装饰的方法执行前后加上想要的逻辑处理进行增强,又可以不改变现有的结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供额外的功能
    使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。
    注意事项:可代替继承

    实战

    我们利用女孩化妆来演示装饰者设计模式,首先我们定义一个接口,拥有展示的行为:

    public interface Showable {
        void show();
    }
    
    

    当然女友会这门功夫了,所以实现了此行为并施展其“美丽的脸庞”了,但此时只是原生态的素颜。

    public class Girl implements Showable {
    
        @Override
        public void show() {
            System.out.print("女孩的素颜");
        }
    }
    

    没什么复杂的,直接调用的话会是素面朝天直面惨淡的人生,这样当然达不到美颜效果了,何以一顾倾城。那么接下来要进行化妆了,这里必须依靠一种神秘而又昂贵的东西,化妆品登场了,它同样实现了Showable接口。

    public class Decorator implements Showable {
    
        /**
        * 拥有某个善于展示的对象
        */
        private Showable showable;
    
        public Decorator(Showable showable){
            this.showable = showable;
        }
        @Override
        public void show() {
            System.out.print("化妆(");
            showable.show();
            System.out.println(")");
        }
    }
    

    我们可以发现,在构造化妆品类的时候可以把女孩给注入进来,目的在于调用女孩的show方法,但对于其原本的具体行为装饰器一无所知,并且没有加入任何逻辑限制,它所做的无非是“画龙点睛”,“锦上添花”。接下来我们来运行一下看结果:

    public class TestShowable {
        public static void main(String[] args) {
            //将需要被加强的对象传递给装饰类
            new Decorator(new Girl()).show();
            //结果:打扮(女孩的素颜)
        }
    }
    

    我们可以看到,只需要新建装饰器的时候把女孩给包装进去就得到了粉饰过的美颜,是不是非常简单?然而此时有女朋友会嫌弃了,“只是打粉底这么简单吗?眼霜呢?口红呢……”。

    好吧,为了满足女友的要求,我们得再多一些设计。想想看这些化妆品,不管是什么都有共同的特性,也就是说他们统统都可以装饰原生态的素颜展示方法show,那我们何不把这些特性抽象出来呢?开始行动,修改我们的装饰类

    public abstract class Decorator implements Showable {
        /**
        * 拥有某个善于展示的对象
        */
        protected Showable showable;
    
        public Decorator(Showable showable){
            this.showable = showable;
        }
        
        public void show() {
            //直接调用,不加任何装饰
            showable.show();
        }
    }
    

    我们把化妆品类给改成抽象类,重写show方法,但不做任何粉饰了,这里我们留给子类具体的某个化妆品去做装饰吧。化妆首先第一步一定要打底了,这里我们首先加入一个口红类:

    public class Lipstick extends Decorator{
    
        public Lipstick(Showable showable) {
            //调用父类构造赋值给成员属性
            super(showable);
        }
    
        @Override
        public void show() {
            System.out.print("涂口红(");
            showable.show();
            System.out.print(")");
        }
    }
    

    涂完口红,最后再喷点香水吧。同样的,我们再定义一个香水类:

    public class Perfume extends Decorator {
    
        public Perfume(Showable showable) {
            super(showable);
        }
    
        @Override
        public void show() {
            System.out.println("喷香水(");
            showable.show();
            System.out.println(")");
        }
    }
    

    最后,我们把女友、口红、香水层层包裹起来并运行,结果如愿以偿。

    public class TestShowable {
    
        public static void main(String[] args) {
            //将需要被加强的对象传递给装饰类,层层包裹起来,每一层都多了一些功能
           new Perfume(new Lipstick(new Girl())).show();
            //结果: 喷香水(涂口红(女孩的素颜))
        }
    }
    

    如果女友对这种淡妆效果还是不满意,我们可以继续添加化妆品类,睫毛膏、眼线、眉笔、腮红等等等等,只需要层层包裹起来,最终实现女友浓妆艳抹的梦想。
    在这里插入图片描述

    我们观察这种装饰器模式结构,是不是似曾相识呢?没错,其实装饰器模式在JDK里就有很多应用,比如Java IO包里的众多流处理类

    new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
    

    当然,流处理类当然要比我们的例子复杂的多,但其基本思想和我们去繁就简的例子异途同归,这些对象就好像是俄罗斯套娃一样层层包裹,层层装饰,每套一层就会多出一些功能出来,我们更可以自由搭配,实现不同的组合功能。
    在这里插入图片描述

  • 相关阅读:
    JavaScript数据类型(第一天)
    数据库的事务隔离级别
    SSH(远程登录)原理
    Hadoop安装
    activiti学习第二天
    activiti学习第一天
    .net调用系统软键盘(兼容win7及win10)
    使用Blend设计出符合效果的WPF界面
    Mysql的收获
    PHP文件上传安全处理的步骤
  • 原文地址:https://www.cnblogs.com/seasail/p/12179391.html
Copyright © 2011-2022 走看看