美文网首页
装饰模式

装饰模式

作者: wuchao226 | 来源:发表于2021-06-21 14:59 被阅读0次

    装饰模式定义

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

    装饰模式使用场景

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

    装饰模式基本代码

    /**
     * 抽象组件类
     */
    public abstract class Component {
        /**
         * 抽象的方法
         */
        public abstract void operate();
    }
    
    /**
     * 组件具体实现类
     */
    public class ConcreteComponent extends Component {
        @Override
        public void operate() {
            // 具体逻辑
            System.out.println("组件具体对象的操作");
        }
    }
    
    /**
     * 抽象装饰者
     */
    public abstract class Decorator extends Component {
        // 持有一个 Component 对象的引用
        private Component component;
    
        /**
         * 必要的构造方法,需要一个 Component 类型的对象
         *
         * @param component Component 对象
         */
        public Decorator(Component component) {
            this.component = component;
        }
    
        @Override
        public void operate() {
            component.operate();
        }
    }
    
    /**
     * 装饰者具体实现类
     */
    public class ConcreteDecoratorA extends Decorator {
        /**
         * 必要的构造方法,需要一个 Component 类型的对象
         *
         * @param component Component 对象
         */
        public ConcreteDecoratorA(Component component) {
            super(component);
        }
    
        @Override
        public void operate() {
            // 装饰方法 A 和 B 即可在父类方法前调用也可在之后调用
            operateA();
            super.operate();
            operateB();
        }
    
        /**
         * 自定义的装饰方法 A
         */
        public void operateA() {
            // 装饰方法逻辑
            System.out.println("为具体构件角色增加额外的功能 operateA()");
        }
    
        /**
         * 自定义的装饰方法 B
         */
        public void operateB() {
            // 装饰方法逻辑
            System.out.println("为具体构件角色增加额外的功能 operateB()");
        }
    }
    

    程序运行结果如下:

    创建具体构件角色
    为具体构件角色增加额外的功能 operateA()
    调用具体构件角色的方法 operate()
    为具体构件角色增加额外的功能 operateB()
    

    角色介绍:

    • Component:抽象组件
      可以是一个接口或抽象类,其充当的就是被装饰的原始对象。
    • ConcreteComponent:组件具体实现类
      该类是 Component 类的基本实现,也是装饰的具体对象。
    • Decorator:抽象装饰者
      为了装饰组件对象,其内部一定要有一个指向组件对象的引用。大多数情况下,该类为抽象类,需要根据不同的装饰逻辑实现不同的具体子类。如果装饰逻辑单一,只有一个的情况下可以省略该类直接作为具体的装饰者。
    • ConcreteDecoratorA:装饰者具体实现
      只是对抽象装饰者作出具体实现。

    装饰模式的简单实现

    人总是要穿衣服的,把人定义为一个抽象类,将穿衣的行为定义为一个抽象方法。

    public abstract class Person {
        /**
         * Person 下有一个穿着的抽象方法
         */
        public abstract void dressed();
    }
    

    该类就是上面提及的抽象组件类,也是我们需要装饰的原始对象,具我们需要一个具体的实现类来具体装饰。

    public class Boy extends Person{
        @Override
        public void dressed() {
            // Boy类下 dressed 方法的基本逻辑
            System.out.println("穿了内衣内裤");
        }
    }
    

    Boy 类继承 Person类,该类仅对 Person 类中的 dressed 方法做了具体实现,而 Boy 类则是我们所要装饰的具体对象,现在需要一个装饰者来装饰 Boy 对象。定义一个 PersonCloth 类来表示人所穿着的衣服。

    public abstract class PersonCloth extends Person {
        // 保持一个 Person 类的引用
        private Person mPerson;
    
        public PersonCloth(Person person) {
            this.mPerson = person;
        }
    
        @Override
        public void dressed() {
            // 调用 Person 类中的 dressed 方法
            mPerson.dressed();
        }
    }
    

    在 PersonCloth 类中保持一个对 Person 类的引用,可以方便的调用具体被装饰对象中的方法。定义两种衣服类型,一个类 ExpensiveCloth 表示高档衣服。

    public class ExpensiveCloth extends PersonCloth {
        public ExpensiveCloth(Person person) {
            super(person);
        }
    
        /**
         * 穿短袖
         */
        private void dressShirt() {
            System.out.println("穿件短袖");
        }
    
        /**
         * 穿皮衣
         */
        private void dressLeather() {
            System.out.println("穿件皮衣");
        }
    
        /**
         * 穿牛仔裤
         */
        private void dressJean() {
            System.out.println("穿件牛仔裤");
        }
    
        @Override
        public void dressed() {
            super.dressed();
            dressShirt();
            dressLeather();
            dressJean();
        }
    }
    

    而另一个类 CheapCloth 表示便宜的衣服。

    public class CheapCloth extends PersonCloth {
        public CheapCloth(Person person) {
            super(person);
        }
    
        /**
         * 穿短裤
         */
        private void dressShorts() {
            System.out.println("穿条短裤");
        }
    
    
        @Override
        public void dressed() {
            super.dressed();
            dressShorts();
        }
    }
    

    这两个类本质上并没有任何区别,两者都是为原本 Boy 类中的 dressed 方法提供功能扩展。不过这种扩展并非是直接修改原有的方法逻辑或结构,更恰当的说,仅仅是在另一个类中将原有的方法和新逻辑进行封装整合而已。最后看看客户类的调用。

    public class Main {
        public static void main(String[] args) {
            // 首先要有一个 Person 男孩
            Person person = new Boy();
            // 穿上高档衣服
            PersonCloth expensiveCloth = new ExpensiveCloth(person);
            expensiveCloth.dressed();
            System.out.println("----------------------");
            // 穿上便宜衣服
            PersonCloth cheapCloth = new CheapCloth(person);
            cheapCloth.dressed();
        }
    }
    

    程序运行结果如下:

    穿了内衣内裤
    穿件短袖
    穿件皮衣
    穿件牛仔裤
    ----------------------
    穿了内衣内裤
    穿条短裤
    

    相关文章

      网友评论

          本文标题:装饰模式

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