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

    概述

    装饰模式(Decorator Pattern)是指动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。

    看下它的结构类图

     下面举个例子,代码实现一个这样的场景,我们早上去煎饼摊买煎饼的场景,煎饼可以加蛋和香肠(扩展)

    首先实现继承来实现看看

    Battercake-煎饼类

    public class Battercake {
        protected String getMsg()
        {
            return "煎饼";
        }
        public int getPrice()
        {
            return 5;
        }
    }

    使用继承BattercakeWithEgg-加鸡蛋

    public class BattercakeWithEgg extends Battercake{
        protected String getMsg()
        {
            return super.getMsg() + "加一个鸡蛋";
        }
        public int getPrice()
        {
            return super.getPrice() + 1;
        }
    }

    加香肠

    public class BattercakeWithEggAndSausage extends BattercakeWithEgg{
        protected String getMsg()
        {
            return super.getMsg() + "加一个香肠";
        }
        public int getPrice()
        {
            return super.getPrice() + 2;
        }
    }

    测试

    public class BattercakeTest {
        public static void main(String[] args) {
            Battercake battercake = new Battercake();
            System.out.println(battercake.getMsg() + ",总价格:" + battercake.getPrice());
    
            Battercake battercakeWithegg = new BattercakeWithEgg();
            System.out.println(battercakeWithegg.getMsg() + ",总价格:" + battercakeWithegg.getPrice());
    
            Battercake battercakeWithEggAndSausage = new BattercakeWithEggAndSausage();
            System.out.println(battercakeWithEggAndSausage.getMsg() + ",总价格:" + battercakeWithEggAndSausage.getPrice());
        }
    }

    结果

    我们可以看出来继承并不灵活,假如我比较额要加两个蛋,两个香肠怎么办,继续添加子类?显然这样不过灵活

    接下来使用装饰模式

    抽象类Battercake,可以对应上面类图Component

    public abstract class Battercake {
        public abstract String getMsg();
        public abstract int getPrice();
    }

    具体对象BaseBattercake,不加任何扩展的煎饼

    public class BaseBattercake extends Battercake{
    
        @Override
        public String getMsg() {
            return "煎饼";
        }
    
        @Override
        public int getPrice() {
            return 5;
        }
    }

    定义抽象装饰类BattercakeDecorator

    public abstract class BattercakeDecorator extends Battercake{
        private Battercake battercake;
    
        public BattercakeDecorator(Battercake battercake) {
            this.battercake = battercake;
        }
    
        @Override
        public String getMsg() {
            return this.battercake.getMsg();
        }
    
        @Override
        public int getPrice() {
            return this.battercake.getPrice();
        }
    }

    具体装饰类-加鸡蛋的装饰类EggDecorator

    public class EggDecorator extends BattercakeDecorator {
    
    
        public EggDecorator(Battercake battercake) {
            super(battercake);
        }
    
        @Override
        public String getMsg() {
            return super.getMsg() + "+一个鸡蛋";
        }
    
        @Override
        public int getPrice() {
            return super.getPrice() + 1;
        }
    }

    具体装饰类-加香肠的装饰类SausageDecorator

    public class SausageDecorator extends BattercakeDecorator {
    
    
        public SausageDecorator(Battercake battercake) {
            super(battercake);
        }
    
        @Override
        public String getMsg() {
            return super.getMsg() + "+一个香肠";
        }
    
        @Override
        public int getPrice() {
            return super.getPrice() + 2;
        }
    }

    测试类,加2个鸡蛋1根香肠

    public class BattercakeDecoratorTest {
        public static void main(String[] args) {
            Battercake battercake = new BaseBattercake();
            battercake = new EggDecorator(battercake);
            battercake = new EggDecorator(battercake);
            battercake = new SausageDecorator(battercake);
            System.out.println(battercake.getMsg() + ",总价:" + battercake.getPrice());
        }
    }

    结果

     会发现基础类很简单,所有的装饰方法与基础方法分开管理,需要的的时候只需要装饰上就好,就好比一个人可以穿很多种类的衣服,但是我们没必要在Person类中把这些装饰的功能增加进去,而是在需要时动态添加

    那么我们什么时候该用装饰模式呢,当我们系统需要新的功能的时候,是向旧的类中添加新的代码,这些新的代码装饰了原有类的核心职责或主要行为,如果在主类中增加新的字段和新的方法无疑增加了类的复杂度,比如期初我们只有一个煎饼类,如果加鸡蛋香肠那么原本的类就会很复杂,新加的东西只是为了满足某个特殊需求,装饰模式提供了很好的解决方案,他把每一个要装饰的功能放在单独的类中,让这个类包装所要装饰的类,所有当有特殊需求时客户端可以有选择、有顺序的选择使用装饰功能

    装饰模式的好处就是有效的把类的核心职责和装饰功能分开

  • 相关阅读:
    Validator 字段验证
    DRF实现发送短信验证码接口
    云片网发送短信验证码
    DRF自定义用户认证
    php服务器端与android客户端通信问题
    转 java调用php的webService
    Ubuntu12.04安装vim7.3
    ubuntu12.10更新源
    源列表
    Ubuntu 12.10 用wubi安装到硬盘中
  • 原文地址:https://www.cnblogs.com/gudazhi/p/10685070.html
Copyright © 2011-2022 走看看