设计模式之装饰者模式

装饰者模式

1、概念

在不改变原类文件以及不使用继承的情况下,动态地将责任附加到对象上,从而实现动态拓展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比子类更为灵活。

2、角色及图例

  • Component(抽象组件):通常是一个抽象类或者一个接口,定义了属性或者方法,方法的实现可以由子类实现或者自己实现。通常不会直接使用该类,而是通过继承该类来实现特定的功能,它约束了整个继承树的行为。比如说,如果Component代表人,即使通过装饰也不会使人变成别的动物。
  • ConcreteComponent(具体组件):是Component的子类,抽象装饰者能给他新增职责,实现了相应的方法,它充当了“被装饰者”的角色。
  • Decorator(抽象装饰者):也是Component的子类,持有一个抽象组件对象的实例,并定义一个与抽象组件一致的接口。。比如说,Decorator代表衣服这一类装饰者,那么它的子类应该是T恤、裙子这样的具体的装饰者。
  • ConcreteDecorator(具体装饰者):是Decorator的子类,是具体的装饰者,给内部持有的具体组件增加具体的职责;由于它同时也是Component的子类,因此它能方便地拓展Component的状态(比如添加新的方法)。每个装饰者都应该有一个实例变量用以保存某个Component的引用,这也是利用了组合的特性。在持有Component的引用后,由于其自身也是Component的子类,那么,相当于ConcreteDecorator包裹了Component,不但有Component的特性,同时自身也可以有别的特性,也就是所谓的装饰。
    -

3、代码演示

 //抽象组件,可以是抽象类,也可以是接口
    public abstract class Person {
        String description = "Unkonwn";

        public String getDescription()
        {
            return description;
        }
        public abstract double cost(); //子类应该实现的方法
    }
    //具体组件
    public  class Adult extends Person {

        public Adult() {
            description = "今天的穿搭:";
        }
        @Override
        public double cost() {
            //什么都没买,不用钱
            return 0;
        }

    }
    //抽象装饰者,可以设置多个
    public abstract class ClothingDecorator extends Person {
        public abstract String getDescription();
    }
    //抽象装饰者
    public abstract class ShoesDecorator extends Person {
        public abstract String getDescription();
    }
	//具体装饰者,可以设置多个
    public class Suit extends ClothingDecorator {
        //用实例变量保存Person的引用
        private Person person;
        public Suit(Person person)
        {
            this.person = person;
        }
        @Override
        public String getDescription() {
            return person.getDescription() + "通勤套装,";
        }
        @Override
        public double cost() {
        	//实现了cost()方法,并调用了person的cost()方法,目的是获得所有累加值
            return 100 + person.cost(); 
        }
    }
	//具体装饰者
    public class Shoes extends ShoesDecorator {
        private Person person;
        public Shoes(Person person) {
            this.person = person;
        }
        @Override
        public String getDescription() {
            return person.getDescription() + "黑色中跟通勤鞋,";
        }
        @Override
        public double cost() {
        	//实现了cost()方法,并调用了person的cost()方法,目的是获得所有累加值
            return 75 + person.cost();
        }
    }

        public static void main(String[] args) {
            Person person = new Adult();
            person = new Suit(person);
            person = new Shoes(person);

            System.out.println(person.getDescription() + "共花费¥ " +person.cost());
        }

在这里插入图片描述

4、模式特点

  • 装饰者(decorator)和被装饰(扩展)的对象有着相同的超类(supertype)。

  • 我们可以用多个装饰者去装饰一个对象。

  • 我们可以用装饰过的对象替换代码中的原对象,而不会出问题(因为他们有相同的超类)。

  • 装饰者可以在委托(delegate,即调用被装饰的类的成员完成一些工作)被装饰者的行为完成之前或之后加上他自己的行为。

  • 一个对象能在任何时候被装饰,甚至是运行时。

5、使用场景

  • 需要扩展一个类的功能,或给一个类添加附加职责。

  • 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

  • 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

  • 当不能采用生成子类的方法进行扩充时。可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。

6、优缺点

优点:

  • Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

  • 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值