• 设计模式之装饰器模式


    1.之前的博客中说过Mybatis中的二级缓存(CachingExecutor为装饰器模式的实现),现在就来说一下装饰器模式。

    2.装饰器模式的作用: 动态的为一个对象添加新的功能,以往我们要增加功能要不修改源代码,要不就是生成自类,非常不灵活。就添加一个功能而言使用装饰器模式更加方便。

    (1).比如说我现在有一个接口为Noodles可以做一碗面,自类中实现为刀削面,方便面。但是我们现在想加个配料(比如鸡蛋,火腿啥的)

    (2).Noodles接口

    public interface Noodles {
        //可以制作一碗面
        public void createABlowOfNoodles();
    }

    (3)DaoXiaoNoodles

    public class DaoXiaodNoodles implements Noodles {
        @Override
        public void createABlowOfNoodles() {
            System.out.println("制作一碗刀削面");
        }
    }

    (4)InstanceNoodles

    public class InstanceNoodles implements Noodles {
        @Override
        public void createABlowOfNoodles() {
            System.out.println("制作一碗方便面");
        }
    }

    (5)BoodlesDecorator (抽象装饰器类,持有被装饰类的引用)

    public abstract class NoodlesDecorator implements Noodles {
        protected Noodles noodles;   //持有一个Noodles的引用,为被装饰的对象
    
        public NoodlesDecorator(Noodles noodles) {  //传入被装饰的对象
            this.noodles = noodles;
        }
    
        @Override
        public void createABlowOfNoodles() {
            noodles.createABlowOfNoodles();
        }
    }

    (6)EggNoodles

    //在面里加个鸡蛋
    public class EggNoodles extends NoodlesDecorator{
        public EggNoodles(Noodles noodles) {
            super(noodles);
        }
    
        @Override
        public void createABlowOfNoodles() {
            noodles.createABlowOfNoodles();   //在装饰器类的实现类中去调用被代理类的方法
            addEgg();              //实现附加功能
        }
    
        private void addEgg(){         //在面里加一个鸡蛋。。。
            System.out.println("加一个鸡蛋");
        }
    }

    (7)HamNoodles

    //在面里加一根火腿
    public class HamNoodles extends NoodlesDecorator{
        public HamNoodles(Noodles noodles) {
            super(noodles);
        }
    
        @Override
        public void createABlowOfNoodles() {
            noodles.createABlowOfNoodles();
            addHam();
        }
    
        private void addHam() {      //在面里加个火腿
            System.out.println("加一根火腿");
        }
    }

    最后我们来看一下怎么使用

    public class Test {
        public static void main(String[] args) {
            Noodles noodles = new EggNoodles(new HamNoodles(new InstanceNoodles()));//制作一碗加蛋,加肠的面
            noodles.createABlowOfNoodles();
        }
    }

    输出为

    相关代码 https://github.com/LiWangCai/blogRelated 可自行获取

  • 相关阅读:
    C#数据库数据导出Excel通用方法
    统计数据库大小的方法
    ashx中使用HttpContext.Current.Session ,出现未将对象引用设置到实例上[转]
    ASP.NET数据库备份[转]
    XDocument读取xml的所有元素以及XPath语法[转]
    Datastage客户端安装 记录
    依赖注入控制反转 (摘抄记录)
    管道处理模型四——MVC原理(摘抄cainong2005博客)
    管道处理模型三(摘抄cainong2005博客)
    管道处理模型二(摘抄cainong2005博客)
  • 原文地址:https://www.cnblogs.com/liwangcai/p/10742669.html
Copyright © 2020-2023  润新知