您的位置:首页 > 其它

设计模式之装饰模式(Decorator)

2015-05-11 16:00 232 查看

场景

我有好多个好多女神,给她们过生日挑选礼物,是个难题。明天是Marry的生日了,送啥礼物喃。不想太破费,毕竟是千斤顶嘛。选一张我俩的合照,在背面写上“Marry女神,生日快乐”,再去买个相框装饰下吧,在外面再套个礼品盒,一个简单而又有心意的礼品就产生了。

不错,以上我们就是对礼物在进行装饰,同样的,对房屋等同样需要装饰,这时就需要我们的装饰模式。

简介

装饰模式是以对客户端透明的模式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。动态的给一个对象增加功能,增加由一些基本功能的排列组合而产生非常大量的功能。

看到这个设计模式,是在java IO中看到的,输入流和输入流,具有相当多的功能,比如处理文件、缓冲、读入和写出数据,如果使用继承的方式,会有很多的组合,就采用了装饰类,具有更大的灵活性。

角色

Component(抽象构件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法

ConcreteComponent(具体构件):它是抽象构件类的子类,用于定义具体的构件对象(被装饰者),实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。

Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。

ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。

UML类图如下所示:



具体实现

程序场景说明:一个女生要去见男朋友,化妆是个大问题,毕竟少女心嘛。

可以选择素颜与化妆,化妆可以画眉毛、涂口红、发型等等不同的化妆方式。可以选择不同的组合,如果使用使用继承的方式会有很多种可能。可以采用装饰模式,利用组合更好的来选择化妆。可以很直观的体现装饰模式的优点。

WomenFace.java

[code]package com.zy.disignpattern;

public interface WomenFace {
    public void outing();

}


WomenFaceImpl.java

[code]package com.zy.disignpattern;

public class WomenFaceImpl implements WomenFace {
    @Override
    public void outing() {
        System.out.println("今天晚上有约会,怎么出门呢");
    }

}


WomenFaceDecorator.java

[code]package com.zy.disignpattern;

public abstract class WomenFaceDecorator implements WomenFace {
    public WomenFace womenFace;

    public WomenFaceDecorator(WomenFace womenFace) {
        this.womenFace = womenFace;
    }

    @Override
    public void outing() {
        // TODO Auto-generated method stub
        this.womenFace.outing();

    }

}


NaturalWomenFaceDecorator.java

[code]package com.zy.disignpattern;

public class NaturalWomenFaceDecorator extends WomenFaceDecorator {
    public NaturalWomenFaceDecorator(WomenFace womenFace) {
        super(womenFace);
    }

    public void outing() {
        super.outing();
        System.out.println("男朋友喜欢素颜,不化妆了吧");
    }

}


EyeBrowWomenFaceDecorator.java

[code]package com.zy.disignpattern;

public class EyeBrowWomenFaceDecorator extends WomenFaceDecorator {
    public EyeBrowWomenFaceDecorator(WomenFace womenFace) {
        super(womenFace);
    }

    public void outing() {
        super.outing();
        System.out.println("画个浓眉毛");
    }

}


LipstickWomenFaceDecorator.java

[code]package com.zy.disignpattern;

public class LipstickWomenFaceDecorator extends WomenFaceDecorator {
    public LipstickWomenFaceDecorator(WomenFace womenFace) {
        super(womenFace);
    }

    public void outing() {
        super.outing();
        System.out.println("画个口红");
    }

}


Test.java

[code]package com.zy.disignpattern;

public class Test {
    public static void main(String[] args) {
        WomenFace womenFace = new WomenFaceImpl();
        womenFace.outing();

        System.out.println("-----------------------");
        NaturalWomenFaceDecorator womenFace1 = new NaturalWomenFaceDecorator(womenFace);
        womenFace1.outing();

        System.out.println("-----------------------");
        EyeBrowWomenFaceDecorator womenFace2 = new EyeBrowWomenFaceDecorator(womenFace);
        womenFace2.outing();

        System.out.println("-----------------------");
        LipstickWomenFaceDecorator womenFace3 = new LipstickWomenFaceDecorator(womenFace);
        womenFace3.outing();

        System.out.println("-----------------------");
        EyeBrowWomenFaceDecorator womenFace4 = new EyeBrowWomenFaceDecorator(new LipstickWomenFaceDecorator(womenFace));
        womenFace4.outing();
    }

}


运行结果

[code]今天晚上有约会,怎么出门呢
-----------------------
今天晚上有约会,怎么出门呢
男朋友喜欢素颜,不化妆了吧
-----------------------
今天晚上有约会,怎么出门呢
画个浓眉毛
-----------------------
今天晚上有约会,怎么出门呢
画个口红
-----------------------
今天晚上有约会,怎么出门呢
画个口红
画个浓眉毛


优缺点

优点:使用装饰模式,能够提供比使用继承关系更灵活的扩展对象的功能,它可以动态地增加对象的功能,并且可以随意地组合这些功能

缺点:因为可以随意的组合功能,有时候可能会出现一些不合理的逻辑。

参考

J***A设计模式之 装饰模式【Decorator Pattern】

Java装饰模式

易学设计模式-郭志学编著
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: