美文网首页
(21)装饰模式

(21)装饰模式

作者: minminaya | 来源:发表于2017-08-09 10:48 被阅读14次

    定义

    动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活。其实通俗的说就说给一个类增加新的功能(解决java不能扩展类方法的问题,kotlin改进了java这个不能扩展的问题)


    使用场景

    • 需要透明且动态的扩展类的功能时

    其实就是扩展父类

    UML图

    装饰模式.png 角色介绍

    简单的例子

    人事要穿衣服的,将人定义为一个抽象类,将穿衣的行为定义为一个抽象方法

    /** 人的抽象类,相当于Component类
     * 
     */
    public abstract class Person {
        /**
         *
         *  Person下有个穿着的抽象方法,
         * */
        public abstract void dressed();
    }
    

    Boy类继承于Person类,该类仅对Person中的dresses方法做了具体的实现,而Boy类就是我们所要装饰的具体对象

    /** Boy类,相当于具体实现类ConcreteComponent类
     * 
     */
    public class Boy extends Person {
    
        @Override
        public void dressed() {
            System.out.println("原始穿着:内衣内裤");
        }
    }
    

    装饰者

    **
     * 抽象的装饰类,类似Decorator类
     * 
     */
    public abstract class PersonCloth extends Person {
    
        protected Person mPerson;//保持一个Person类的引用
    
        public PersonCloth(Person mPerson) {
            this.mPerson = mPerson;
        }
    
        @Override
        public void dressed() {
            //调用Person类中的dressed方法
            mPerson.dressed();
        }
    }
    

    具体的装饰类,其实就是为了Boy类提供扩展

    /** 昂贵的 本质上仅仅是将原有方法和新逻辑进行封装整合了
     * 具体的装饰类,类似ConcreteDecoratorA
     *
     */
    public class ExpensiveCloth extends PersonCloth {
    
        public ExpensiveCloth(Person mPerson) {
            super(mPerson);
        }
    
        private void dressShirt() {
            System.out.println("装饰:穿上了短袖");
        }
    
        private void dressLeather() {
            System.out.println("装饰:穿上了皮衣");
        }
    
        private void dressJean() {
            System.out.println("装饰:穿上了牛仔裤");
        }
    
        @Override
        public void dressed() {
            super.dressed();//这里就是Boy类的原始方法,只穿内裤内衣
            dressShirt();
            dressLeather();
            dressJean();
        }
    }
    
    /** 便宜的
     * 具体的装饰类,类似ConcreteDecoratorA
     * 
     */
    public class CheapCloth extends PersonCloth {
    
        public CheapCloth(Person mPerson) {
            super(mPerson);
        }
    
        private void dressShorts() {
            System.out.println("装饰:穿上了短裤");
        }
    
    
        @Override
        public void dressed() {
            super.dressed();
            dressShorts();
        }
    }
    
    ** 测试类
     * 
     */
    public class Test {
        public static void main(String[] args){
            //首先要有一个Person男孩
            Person person = new Boy();
            //然后为他穿上便宜的衣服
            PersonCloth cheapCloth = new CheapCloth(person);
            cheapCloth.dressed();
    
            System.out.println();
            System.out.println();
            System.out.println();
            //或者穿上贵的衣服
            PersonCloth expensiveCloth = new ExpensiveCloth(person);
            expensiveCloth.dressed();
        }
    }
    
    
    结果:
    
    原始穿着:内衣内裤
    装饰:穿上了短裤
    
    
    
    原始穿着:内衣内裤
    装饰:穿上了短袖
    装饰:穿上了皮衣
    装饰:穿上了牛仔裤
    
    

    例子UML类图


    优点

    • 扩展类方法

    缺点

    • 和代理模式易混淆
      装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案(为装饰的对象增强功能)
      代理模式:给对象提供一个代理对象,并用代理对象来控制对原有对象的引用(对代理的对象施加控制,但不对对象本身的功能进行增强)

    源代码:DesignPattern



    参考

    《Android源码设计模式解析与实战读书》
    各大佬博客


    end

    相关文章

      网友评论

          本文标题:(21)装饰模式

          本文链接:https://www.haomeiwen.com/subject/xsaxrxtx.html