zoukankan      html  css  js  c++  java
  • 设计模式——装饰模式

    定义:

    装饰模式(Decorator),在不改变对象的前提下,动态给对象增加一些功能。

    对于,增加功能而言,装饰者模式比增加子类更灵活。

    如果想给一个特定的类A增加功能,我们一般采用两种模式:

    1,继承该A,利用其子类在实现这个A的函数的同时,增加一些新的方法。这个方法是静态的,我们不能通过继承来实现动态的匹配。

    而且,当类比较多的时候,容易发生类爆炸。(下面的例子会解析类爆炸)

    2,利用装饰模式,给类一个抽象类B,让装饰类D和类A同时继承与这个抽象类B。

    通过装饰类D和类A的组合来达到为类A增加功能的目的。这样的增加是动态的。随意我们在客户端组合的。

    UML图:

    Demo:

    业务场景:一个人(男人)去买帽子。(帽子可能是红的,黑的,白的,嗯...绿的~)总之男生去买的帽子不知道几个,而且不知道颜色。

    解决方案:

    1,通过类的继承,如果我们给每种可能去创建一个类的话,那就出现了类爆炸了。

    2,当我们使用装饰模式的时候。我们可以动态的组装其购买。

    废话不多说,代码里来参悟!

    超级父类(超类):

    public abstract class Person {
        String description;
    
        public String getDescription() {
            return description;
        }
    
        // 计算其花了多少钱
        public abstract int cost();
    }

    被修饰的类:(man)

    public class Man extends Person {
    
        public Man() {
            description = "这个男生";
        }
    
        @Override
        public int cost() {
            return 0;
        }
    
    }

    抽象修饰类:(为了迎合我们的开放封闭原则,定义一个抽象类,毕竟以后店家除了绿帽子还会出售其他的颜色帽子)

    public abstract class Hat extends Person {
        public abstract String getDescription();
    }

    修饰类:(多个)

    public class RedHat extends Hat {
    
        Person person;
    
        public RedHat(Person person) {
            super();
            this.person = person;
        }
    
        @Override
        public String getDescription() {
    
            return person.getDescription() + "买了红帽子";
        }
    
        @Override
        public int cost() {
            return person.cost() + 1;
        }
    
    }
    public class BlackHat extends Hat {
        Person person;
    
        public BlackHat(Person person) {
            super();
            this.person = person;
        }
    
        @Override
        public String getDescription() {
            return person.getDescription() + "买了黑帽子";
        }
    
        @Override
        public int cost() {
            // TODO Auto-generated method stub
            return person.cost() + 100;
        }
    
    }

    等各种颜色的帽子。

    客户端:

    public class Client {
        public static void main(String[] args) {
            // 实力化被装饰者(man)
            Person person = new Man();
            person = new RedHat(person);
            person = new BlackHat(person);
            System.out.println(person.getDescription() + "花费了" + person.cost());
        }
    }

    利用装饰模式,我们就可以很好的实现了男生购物车的拼接~

    总结:

    如果给一个类很多的功能,我们可以采取继承,但是如果我们需要很多功能的之间的灵活的组合,如果还是采用继承的话,我们就要创建N多的子类,这样就形成了类爆炸了。

    但是,如果我们采用装饰模式来解决的话,只需要为每个功能创建一个修饰类,客户端根据需求直接组装不同的对象就好啦。灵活性得到了很大的提升~

  • 相关阅读:
    mysql联合主键自增、主键最大长度小记
    针对list集合进行分页展示
    初识javascript变量和基本数据类型
    12.19如何定义正则表达式
    人民币符号在html的显示方法
    windows下的NodeJS安装
    css 实现未知图片垂直居中
    IE678下placeholder效果,支持文本框和密码框
    jvm004 解析与分派
    jvm003 类加载的过程
  • 原文地址:https://www.cnblogs.com/tujietg/p/10252300.html
Copyright © 2011-2022 走看看