• 设计模式-装饰者模式


    一、定义

    定义:在不改变原有对象的基础上,将功能附加到对象上

    提供了比继承更有弹性的替代方案(扩展原有对象功能)

    类型: 结构型

    二、使用场景

    扩展一个类的功能或者给一个类添加附件职责

    动态给一个对象添加功能,这些功能可以再动态的撤销

    三、优点

    继承的有力补充,比继承灵活,不改变原有对象的情况下给对象一个扩展功能

    通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同的效果

    符合开闭原则

    四、缺点

    会出现更多的代码,更多的类,增加程序的复杂性

    动态装饰时,多层装饰时会更复杂

    五、相关设计模式

    1. 装饰者模式和代理模式

    装饰者模式关注一个对象动态添加方法

    代理模式关注控制对对象的访问

    六、Coding

     1. 创建BatterCake 类

    /**
     * 煎饼
     */
    public class BatterCake {
    
        protected   String getDesc(){
            return  "煎饼";
        }
    
        protected  int cost(){
            return  8;
        }
    }
    

      

    2. 创建BatterCakeWithEgg

    public class BatterCakeWithEgg  extends  BatterCake{
        @Override
        public String getDesc() {
            return super.getDesc() + " 加一个鸡蛋";
        }
    
        @Override
        public int cost() {
            return super.cost() + 1;
        }
    }
    

      

    3. 创建BatterCakeWithEggSausage类

    public class BatterCakeWithEggSausage  extends  BatterCakeWithEgg{
        @Override
        public String getDesc() {
            return super.getDesc() + " 加一根香肠";
        }
    
        @Override
        public int cost() {
            return super.cost() + 2;
        }
    }
    

      

    4. 测试类

    public class Test {
        public static void main(String[] args) {
            BatterCake batterCake = new BatterCake();
            System.out.println(batterCake.getDesc() + " 销售价格:" + batterCake.cost());
    
            BatterCakeWithEgg batterCakeWithEgg = new BatterCakeWithEgg();
            System.out.println(batterCakeWithEgg.getDesc() + " 销售价格:" + batterCakeWithEgg.cost());
    
            BatterCakeWithEggSausage batterCakeWithEggSausage = new BatterCakeWithEggSausage();
            System.out.println(batterCakeWithEggSausage.getDesc() + " 销售价格:" + batterCakeWithEggSausage.cost());
        }
    
    
    }

    缺点:不能增加个数,如需要两个鸡蛋和两个火腿肠

    七、Coding(改进版本)

     1. 创建ABatterCake抽象类

    public abstract class ABatterCake {
        protected  abstract String getDesc();
    
        protected  abstract int cost();
    }
    

      

    2. 创建BatterCake类  

    public class BatterCake  extends  ABatterCake{
        @Override
        protected String getDesc() {
            return "煎饼";
        }
    
        @Override
        protected int cost() {
            return 8;
        }
    }
    

      

    3. 创建AbstractDecorator。 这里可以不用抽象类

    public abstract class AbstractDecorator extends ABatterCake {
    
        private  ABatterCake aBatterCake;
    
        public  AbstractDecorator(ABatterCake aBatterCake){
            this.aBatterCake = aBatterCake;
        }
    
        protected abstract  void doSomething();
    
        @Override
        protected String getDesc() {
            return this.aBatterCake.getDesc();
        }
    
        @Override
        protected int cost() {
            return this.aBatterCake.cost();
        }
    }
    

      

    4. 创建装饰类 EggDecorator  

    public class EggDecorator  extends  AbstractDecorator{
        public EggDecorator(ABatterCake aBatterCake) {
            super(aBatterCake);
        }
    
        @Override
        protected void doSomething() {
    
        }
    
        @Override
        protected String getDesc() {
            return super.getDesc() + " 加一个鸡蛋";
        }
    
        @Override
        protected int cost() {
            return super.cost() + 1;
        }
    }
    

     

    5. 创建装饰类

    public class SausageDecorator  extends  AbstractDecorator{
    
        public SausageDecorator(ABatterCake aBatterCake) {
            super(aBatterCake);
        }
    
        @Override
        protected void doSomething() {
    
        }
    
        @Override
        protected String getDesc() {
            return super.getDesc() + "加一根香肠";
        }
    
        @Override
        protected int cost() {
            return super.cost() + 2;
        }
    }
    

      

    6. 创建测试类

    public class Test {
    
        public static void main(String[] args) {
            ABatterCake aBatterCake = new BatterCake();
            aBatterCake = new EggDecorator(aBatterCake);
            aBatterCake = new EggDecorator(aBatterCake);
            aBatterCake = new EggDecorator(aBatterCake);
            System.out.println(aBatterCake.getDesc() + " 销售价格:" + aBatterCake.cost());
    
    
    
        }
    }
    

      

    7. UML图

    八、装饰者模式在源码中的应用

     1.java.io包下的BufferedReader类

    继承于Reader抽象类。BufferedReader的构造器如下

        public BufferedReader(Reader var1, int var2) {
            super(var1);
            this.markedChar = -1;
            this.readAheadLimit = 0;
            this.skipLF = false;
            this.markedSkipLF = false;
            if(var2 <= 0) {
                throw new IllegalArgumentException("Buffer size <= 0");
            } else {
                this.in = var1;
                this.cb = new char[var2];
                this.nextChar = this.nChars = 0;
            }
        }
    

      

    2. BufferedOutputStream和BufferedInputStream

    BufferedOutputStream继承自FilterOutputStream, FilterOutputStream继承自OutputStream

    BufferedOutputStream的构造器

        public BufferedOutputStream(OutputStream var1, int var2) {
            super(var1);
            if(var2 <= 0) {
                throw new IllegalArgumentException("Buffer size <= 0");
            } else {
                this.buf = new byte[var2];
            }
        }
    

      

     3. FilterInputStream是一个装饰者,LineInputStream,BufferedInputStream,DataInputStream是实际的装饰者。

    4. 在spring中的TransactionAwareCacheDecorator类

    public class TransactionAwareCacheDecorator implements Cache {
        private final Cache targetCache;
    
        public TransactionAwareCacheDecorator(Cache targetCache) {
            Assert.notNull(targetCache, "Target Cache must not be null");
            this.targetCache = targetCache;
        }
    }
    

      

    5. Mybatis中的org.apache.ibatis.cache.Cache类

    例如FifoCache 类

    public class FifoCache implements Cache {
        private final Cache delegate;
        private Deque<Object> keyList;
        private int size;
    
        public FifoCache(Cache delegate) {
            this.delegate = delegate;
            this.keyList = new LinkedList();
            this.size = 1024;
        }
    }
    

      

  • 相关阅读:
    可重入函数
    epoll源码深度剖析
    数据结构学习之基本概念
    机器学习算法原理与编程实践之朴素贝叶斯分类
    机器学习算法与编程实践之中文文本分类
    ElasticSearch常用结构化搜索
    linux几种常见的文件内容查找和替换命令
    List遍历时删除遇到的问题
    初学ElasticSeacher
    从jar中读取资源文件的问题
  • 原文地址:https://www.cnblogs.com/linlf03/p/9750146.html
Copyright © 2020-2023  润新知