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

    一、建造者模式介绍

    1、定义与类型

    定义:在不改变原有对象的基础之上,将功能附加到对象上
    提供了比继承更有弹性的替代方案(扩展原有对象功能)
    类型:结构型

    2、适用场景

    扩展一个类的功能或给一个类添加附加职责
    动态的给一个对象添加功能,这些功能可以再动态的撤销

    3、优点

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

    4、缺点

    会出现更多的代码,更多的类,增加程序复杂性
    动态装饰时,多层装饰时会更复杂

    5、相关设计模式

    装饰者模式和代理模式
    装饰者模式和适配器模式

    二、代码示例

    模拟场景:买煎饼,有些人可能想要加一个鸡蛋,有些人要加两个鸡蛋,有些人要加一根香肠

    1、v1版本:

    煎饼类:

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

    煎饼 + 鸡蛋类:

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

    煎饼 + 鸡蛋 + 香肠类:

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

    测试类:

    public class Test {
        public static void main(String[] args) {
            Battercake battercake = new Battercake();
            // 输出:煎饼 销售价格:8
            System.out.println(battercake.getDesc()+" 销售价格:"+battercake.cost());
            
            Battercake battercakeWithEgg = new BattercakeWithEgg();
            // 输出:煎饼 加一个鸡蛋 销售价格:9
            System.out.println(battercakeWithEgg.getDesc()+" 销售价格:"+battercakeWithEgg.cost());
    
            Battercake battercakeWithEggSausage = new BattercakeWithEggSausage();
            // 输出:煎饼 加一个鸡蛋 加一根香肠 销售价格:11
            System.out.println(battercakeWithEggSausage.getDesc()+" 销售价格:"+battercakeWithEggSausage.cost());
        }
    }
    

    类图:

    2、v2版本:

    抽象被装饰类:

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

    具体被装饰类:

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

    抽象装饰类(继承被装饰类):

    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();
        }
    }
    

    具体装饰类1(间接继承被装饰类):

    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;
        }
    }
    

    具体装饰类2(间接继承被装饰类):

    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;
        }
    }
    

    测试类:

    public class Test {
        public static void main(String[] args) {
            ABattercake aBattercake = new Battercake();
            aBattercake = new EggDecorator(aBattercake);
            aBattercake = new EggDecorator(aBattercake);
            aBattercake = new SausageDecorator(aBattercake);
            // 输出  煎饼 加一个鸡蛋 加一个鸡蛋 加一根香肠 销售价格:12
            System.out.println(aBattercake.getDesc()+" 销售价格:"+aBattercake.cost());
        }
    }
    

    类图:

    三、源码示例

    1、JDK

    bufferedReader

    JDK中的IO流使用了很多装饰者模式,使用的时候如果能识别出,哪些是抽象被装饰者,哪些是实际被装饰者,哪些是抽象装饰者,哪些是实际装饰者,对于理解是很有益处的。

    2、SPRING

    TransactionAwareCacheDecorator

    SessionRepositoryRequestWrapper

    3、Mybatis


  • 相关阅读:
    docker
    手动处理datanode磁盘间使用不均的问题
    Hadoop op 1)
    Python class and function json
    scala Basic 第三课
    spark streaming kafka example
    hadoop io PART1
    elasticsearch 集群搭建
    Scala编程第二课
    scala 第一课
  • 原文地址:https://www.cnblogs.com/weixk/p/12950277.html
Copyright © 2011-2022 走看看