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

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

    最复杂的应该是这种情况:(多个装饰者和多个被装饰者)(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,就像上图图二一样。

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

  • 相关阅读:
    内存管理简介之Buddy算法和slab分配
    进程通信方式介绍
    Linux内核网络栈实现分析(十一)驱动程序层(下)
    Linux内核网络协议栈深入分析(二)sk_buff的操作函数
    Linux内核网络协议栈深入分析(一)与sk_buff有关的几个重要的数据结构
    内核源码学习:伙伴算法
    寒假Day16Dinic模板更新+优化
    寒假Day20:数位dp
    寒假Day21:Catalan Square卡特兰数 JAVA写大数
    寒假Day17UVALive3231Fair Share(最大流+二分)
  • 原文地址:https://www.cnblogs.com/M-Anonymous/p/13185323.html
Copyright © 2011-2022 走看看