• 装饰者模式


    装饰者模式的核心就是 装饰者 和 被装饰者 必须是共同的类型,可以是实现共同的接口,或者拥有共同的祖先。

    最复杂的应该是这种情况:(多个装饰者和多个被装饰者)(BaseClass 和 Decorator 都是抽象类,)

    看到上图,可能有些人就要问了,DecoratorX 和 DecoratorY 能不能直接继承 BaseClass 呢?

    在装饰者数量不多的话这样也是可以的,但是比较这两个图,你会发现第一个图结构层次更鲜明,而且更方便管理装饰者。

    如果被装饰者只有一个的话,而且装饰者不多的情况下你甚至可以这样:

    接下来看个简单的例子吧:(第二个图)

    package algorithm.demo;
    
    public abstract class Chicken {
        
        private String name;
        
        public abstract void lay_eggs();
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    package algorithm.demo;
    
    public class Hen extends Chicken {
        @Override
        public void lay_eggs() {
            // TODO Auto-generated method stub
            System.out.println("I'm laying eggs");
        }
    }
    package algorithm.demo;
    
    public class DecoratorX extends Chicken {
    
        private Chicken chicken;
        
        public DecoratorX(Chicken chicken) {
            this.chicken = chicken;
        }
        
        @Override
        public void lay_eggs() {
            // TODO Auto-generated method stub
            sing_A_Song();
            chicken.lay_eggs();
            
        }
        
        public void sing_A_Song() {
            System.out.println("Before laying eggs,I'd like to sing a song!");
        }
    
    }
    package algorithm.demo;
    
    public class DecoratorY extends Chicken {
    
        private Chicken chicken;
        
        public DecoratorY(Chicken chicken) {
            this.chicken = chicken;
        }
        
        @Override
        public void lay_eggs() {
            // TODO Auto-generated method stub
            chicken.lay_eggs();
            sing_A_Song();
            
        }
        
        public void sing_A_Song() {
            System.out.println("After laying eggs,I'd like to sing a song!");
        }
    
    }
    package algorithm.demo;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            Chicken chicken = new Hen();
            chicken.lay_eggs();
            System.out.println();
            chicken = new DecoratorX(chicken);
            chicken.lay_eggs();
            System.out.println();
            chicken = new DecoratorY(chicken);
            chicken.lay_eggs();
        }
    
    }

    结果如下图所示:

    通过装饰者模式,我们实现了让母鸡在下蛋前后有了唱歌的行为,扩展了 lay_eggs 的方法。

    看到上面的代码你可能看到装饰者的局限性,扩展的行为只能是 BaseClass 里面有的,换句话说,就是只能扩展已有的方法。

    那能不能给 BaseClass 添加新的方法呢?答案是可以的,不过你得保证添加新的方法的装饰者必须得在最外层。

    package algorithm.demo;
    
    public class DecoratorZ extends Chicken {
        
    private Chicken chicken;
        
        public DecoratorZ(Chicken chicken) {
            this.chicken = chicken;
        }
        
        @Override
        public void lay_eggs() {
            // TODO Auto-generated method stub
            chicken.lay_eggs();
        }
        
        public void fly() {
            System.out.println("咯唧咯唧,I can fly...");
        }
    }
    DecoratorZ fly_chicken = new DecoratorZ(chicken);
    fly_chicken.fly();

    那么如果 BaseClass 是一个接口的话呢,若是这样的话,Decorator 就是 BaseClass,就像上图图二一样。

    以上纯属个人见解,如有同感,皆大欢喜!若有谬论,还请指正!

  • 相关阅读:
    知识点:定义input type=file 样式的方法(转)
    笔记:认识 head 标签 待 更新中……
    检讨:关于上班迟到那么‘ 一两分钟 ’的事儿
    js--局部变量
    数十万互联网从业者的共同关注!
    js--javascript中字符串常用操作总结、JS字符串操作大全
    JavaScript中浏览器兼容问题
    js--性能优化(转)
    js-知识点
    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法--(转)
  • 原文地址:https://www.cnblogs.com/M-Anonymous/p/13185323.html
Copyright © 2020-2023  润新知