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类中把这些装饰的功能增加进去,而是在需要时动态添加

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

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

  • 相关阅读:
    Liferay7 BPM门户开发之34: liferay7对外服务类生成(RestService Get Url)
    Liferay7 BPM门户开发之33: Portlet之间通信的3种方式(session、IPC Render Parameter、IPC Event、Cookies)
    Liferay7 BPM门户开发之32: 实现自定义认证登陆(定制Authentication Hook)
    Liferay7 BPM门户开发之30: 通用帮助类Validator、ArrayUtil、StringUtil等使用
    Liferay7 BPM门户开发之29: 核心kernel.util包下面的通用帮助类ParamUtil、GetterUtil使用
    Liferay7 BPM门户开发之28: Portlet文件上传,及实体类同步更新上传
    Liferay7 BPM门户开发之26: 集成Activiti到Liferay7
    Liferay7 BPM门户开发之27: MVC Portlet插件工程开发
    Liferay7 BPM门户开发之25: Liferay7应用程序配置(APPLICATION CONFIGURATION)
    Liferay7 BPM门户开发之24: Liferay7应用程序安全
  • 原文地址:https://www.cnblogs.com/gudazhi/p/10685070.html
Copyright © 2011-2022 走看看