设计模式系列之十一:装饰者模式

前言

装饰者模式属于结构型设计模式,它可以动态地为对象添加额外的只能,就这点来看,装饰者模式比生成子类更加灵活。既然是结构型设计模式,那么装饰者模式的结构优势体现在哪里呢?有一个组件类,有一个具体的组件类,这个具体的组件类就是要被装饰的对象,还有一个装饰者类,其继承了组件类,对于组件类来说不需要知道这个装饰者类对象的存在,因为装饰者对象真正发挥作用的对象是具体的组件类。要注意的是,组件类和装饰者类都是抽象类,为什么这么设计呢?这点其实很好理解,因为对于每一个具体的组件来说,可能装饰的花样不同,则具体的实现也就不同,把装饰者类设计成抽象类就可以把具体的装饰过程交给子类装饰者了,从而提高软件的灵活性。这同时也体现了依赖倒转原则,实现不应该依赖于细节而应该依赖于抽象

ok,说了那么多还不如来一张装饰者模式的结构图:

现在,可以对装饰者模式有一个清晰的认识了。以穿衣打扮作为例子说明装饰者模式在编码中的应用:

编码实践

package rhwayfun;

public class DecoratorMode{

    //abstract person
    public abstract class Person{
        //name
        protected String name;
        public Person(){}
        public Person(String name){this.name = name;}
        //show the appearance
        public abstract void show();
    }

    //boy
    public class Boy extends Person{
        public Boy(String name ){super(name);}

        public void show(){
            System.out.println("I am a boy named " + name);
        }
    }

    //girl
    public class Girl extends Person {
        public Girl(String name ){super(name);}

        public void show(){
            System.out.println("I am a girl named " + name);
        }
    }

    //abstract decorator
    public abstract class Finery extends Person{
        protected Person person;
        public void decorateComponent(Person person){
            this.person = person;
        }
        public abstract void show();
    }

    //concrete decoratorA of Boy
    public class TShirt extends Finery{
        public void show(){
            person.show();
            System.out.println("dashing T-shirt");
        }
    }

    //concrete decoratorB of Boy
    public class Jeans extends Finery{
        public void show(){
            person.show();
            System.out.println("fashoin Jeans");
        }
    }

    //concrete decoratorB of girl
    public class Skirt extends Finery {
        public void show(){
            person.show();
            System.out.println("beautiful skirt");
        }
    }

    //concrete decoratorB  of girl
    public class Hat extends Finery {
        public void show(){
            person.show();
            System.out.println("white hat");
        }
    }

    //concrete decoratorC of girl
    public class HighHeeledShoes extends Finery {
        public void show(){
            person.show();
            System.out.println("sexy high-heel shoes");
        }
    }

    //test case
    public static void main(String[] args){
        DecoratorMode dm = new DecoratorMode();

        Boy boy = dm.new Boy("xiaofan");
        Girl girl = dm.new Girl("rhway");

        Finery tshirt = dm.new TShirt();
        Finery jeans = dm.new Jeans();
        tshirt.decorateComponent(boy);
        jeans.decorateComponent(tshirt);
        jeans.show();

        System.out.println("**********");

        Finery skirt = dm.new Skirt();
        Finery hat = dm.new Hat();
        Finery highheeledshoes = dm.new HighHeeledShoes();
        skirt.decorateComponent(girl);
        hat.decorateComponent(skirt);
        highheeledshoes.decorateComponent(hat);
        highheeledshoes.show();
    }
}

测试结果:

从上面的代码中可以体会到装饰者模式的使用方法。一般而言,如果当需要向新系统中添加新的功能的时候,可能需要添加新的字段、方法和逻辑,这样一般会增加复杂度。注意,这么说有一个前提,当新增加的功能不是核心功能,因为核心功能是系统运行必须增加的方法或者逻辑,这点复杂度的增加是必须得接受的。那么如果是非核心功能,那么如果一直都是添加在原有的类中就会使得类越来越臃肿,系统维护的难度会逐渐增加。那么怎么解决这个问题呢?根据设计模式中单一职责原则,类中的方法越来越多肯定不是一件好事,使用装饰者模式可以很好解决这个问题。装饰者模式把一要新增加的字段、方法和逻辑从原有的类中移除,并创建一个新的类,成为装饰者类。当系统需要这个方法的时候,就可以根据需要灵活地选用装饰者了。这样就把核心功能与装饰功能分开了,从而可以有效去除重复的逻辑代码。

时间: 2025-01-30 05:08:51

设计模式系列之十一:装饰者模式的相关文章

传统设计模式(三)装饰者模式

说到这个模式的项目实例 虫子也满头疼的 所谓装饰者模式说白了动态将职责附加到对象上.如果你在项目某个场景中需要功能扩展根据基类衍生出非常多的子类,那么装饰者模式无疑是很好的.不过其实在实际的项目中,往往大家不直接衍生子类,而是通过组合的方式,根据逻辑讲各种扩展叠加来,对外公布的只是一个标签一个壳而已. 所以这个章节,虫子就虚构一个实例了.还拿电商来说.点券赠品系统. 背景: 1.所有点券.优惠券.赠品券.积分继承同一个基类 基类券 2.不用种类的券可以混合搭配 3.积分根据不同的场景可以配置不同

设计模式(八)装饰器模式Decorator(结构型)

1. 概述        若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法,或者须要给方法添加更多的功能(魅力),你也许会仅仅继承这个类来产生一个新类-这建立在额外的代码上.       通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静态的,用户不能控制增加行为的方式和时机.如果  你希望改变一个已经初始化的对象的行为,你怎么办?或者,你希望继承许多类的行为,改怎么办?前一个

举例讲解Java设计模式编程中Decorator装饰者模式的运用_java

概念 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 装饰者和被装饰对象有相同的超类型. 你可以用一个或多个装饰者包装一个对象. 既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合 ,可以用装饰过的对象代替它. 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的. 对象可以在任何时候被装饰,所以可以在运行时动态地.不限量地用你喜欢的装饰者来装饰 对象. 在Java中,io包下的很多类就是典型的装饰

设计模式系列之一:简单工厂模式

前言 设计模式能够帮助我们设计出健壮,低耦合性的代码,从此和高耦合的代码say goodbye!在所有的的设计模式中,简单工厂算是我们平时接触比较多的吧,多线程中的消费者工厂类与生产者工厂类应该算是接触最早的设计模式,简单工厂模式要解决的首要问题就是降低程序之间的耦合度,通过Java中的封装.继承与多态实现解耦.通过使用简单工厂模式,我们设计的代码更易于维护和复用 问题背景 在进入正题之前我们先看一下问题背景: 某公司开发了一个A软件,数据库使用的是SQLServer.后由于客户要求需要使用Or

设计模式系列之十:命令模式

前言 命令模式属于行为型设计模式.所谓命令,肯定有命令的发送者以及命令的接收者,命令模式则是命令本身封装成一个对象,从而使得命令接收者可以根据接收到的命令让不同的命令执行者执行具体的命令,使用命令模式可以让命令请求者排队并记录命令日志.命令模式可以使你可用不同的请求对客户参数化.很显然,通过使用命令模式可以较容易地设计一个命令队列,最重要的是命令模式把命令请求的对象与具体执行命令的对象分隔开了,这样具体的命令执行者与命令请求者之间的耦合度就降低了.使用命令模式可以很容易添加命令撤销的操作,但是一

设计模式系列之三:抽象工厂模式

前言 在设计模式有三个模式是与工厂模式相关的,分别是:简单工厂模式.工厂方法模式以及抽象工厂模式.在前面的文章中已经谈到前面两种,这里就对抽象工厂模式介绍一下.抽象工厂模式就是提供一个创建一系列相关或者相互依赖的接口(也就是抽象类),而无需指定具体的类.简单来说,就是当我们需要创建一个具体的对象的时候,我们不必指定该具体的对象,只需要使用它的上层接口直接调用就行.好像还是很抽象哦,好吧,为了更清晰领悟这个设计模式,我们还是通过一个案例来说明 问题背景 某公司开发了一个A软件,数据库使用的是SQL

Java设计模式(二十一)----访问者模式

访问者模式 一.概述 1.定义 2.分派的概念 3.分派的类型 4.双重分派 二.结构 三.具体案例 一.概述 1.定义 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. 2.分派的概念 变量被声明时的类型叫做变量的静态类型(Static Type),有些人又把静态类型叫做明显类型(Apparent Type):而变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type).比如: List list = n

设计模式学习笔记(十一)—Prototype原型模式

Prototype模式的意图是: 通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象. 在java的类库中已经实现了这一模式,只要你定义的类实现了Cloneable接口,用这个类所创建的对象可以做为原型对象进而克隆出更多的同类型的对象.下面举个例子,来介绍简单的介绍一下它的使用. import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java

(Head First 设计模式)学习笔记(3) --装饰者模式(StarBuzz咖啡店实例)

以下内容转载请注明来自"菩提树下的杨过(http://blog.sqlsky.com)" 应用概述: StarBuzz咖啡店有很多饮料,每种饮料都可以根据客户需要加一些调料,比如深培咖啡可以加摩卡(或双倍摩卡),而且某些饮料可以分为大中小杯,根据容量不同,售价不同,而且调料的价格根据饮料的容量不同而不同(比如大杯咖啡加糖要1元,中杯咖啡加糖要0.9元等) 又一设计原则: 对扩展开放,对修改关闭(本例中各种饮料都有共同的大中小杯特性--这是关闭的部分,另外各种具体子类饮料和调料的描述和价