当前位置:编程学习 > JAVA >>

设计模式之我见--3 装饰模式

本文所写都是自己的理解,可能会有错误,如果有错误请指出。

在编程中我们可能会遇到类似的情况:一个功能它有好多的步骤,不同的步骤没有一定的顺序,可以组合,但是不同的组合会产生不同的效果,如果我们针对每一种组合都需要写一个程序,那么可能我们会累死。另外在以后如果组合改变的时候,我们改变也很不容易。类比生活中的例子:我们在穿衣服的时候,可以任意搭配,但是如果我们将一个组合固定下来,那么我们穿衣服的时候就有很大的局限性。这就类似我们将程序的步骤组合在一个程序中。但是实际情况是,我们的衣服都是独立存在的,它们之间没有太多的依赖关系,我们想怎么穿就怎么穿。同样我们想在程序中实现类似的功能,那么装饰模式就是一个很好的选择。

就拿穿衣服来说,比如我们准备穿大T恤、跨裤、破球鞋,可能我们在一个程序中写上穿了大T恤、跨裤、破球鞋,但是如果我们想转换一下顺序那么我们就得另外再写一个程序了。装饰模式解决了这样的一个问题,装饰模式可以动态的为一些对象增加一些职责,我们这里就是动态的穿衣服。这样说可能也不明白,先看代码吧。

 

这里有一个人的类,代表我们需要真正穿衣服的人,下面的服饰是一个父类,里面存储了一个我们穿衣服的人的实例,服饰类有三个子类分别代表不同的衣服。

[java] 
package PersonDecorate; 
 
public class Person 

    public Person() {  
    } 
    private String name; 
    public Person(String name){ 
        this.setName(name); 
    } 
    public void Show(){ 
        System.out.println("装扮的"+ name); 
    } 
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 

[java] 
package PersonDecorate; 
 
class Finery extends Person { 
 
    protected Person component; 
    public void Decorate(Person component){ 
        this.component = component; 
    }    
    @Override 
    public void Show(){ 
        if(component != null){ 
            component.Show(); 
        } 
    } 

[java] view plaincopy
package PersonDecorate; 
 
class TShirts extends Finery { 
    public void Show(){ 
        System.out.println("大T恤"); 
        super.Show(); 
    } 

[java] 
package PersonDecorate; 
 
class BigTrousers extends Finery { 
    public void Show(){ 
        System.out.println("跨裤"); 
        super.Show(); 
    } 

[java]  
package PersonDecorate; 
 
class Sneakers extends Finery { 
    public void Show(){ 
        System.out.println("破球鞋"); 
        super.Show(); 
    } 

这个比较简单,几件衣服都是继承了服饰类,同样也继承了服饰类的Decorate方法,这个方法实际上就是设置穿衣服的人,但是这时候这个穿衣服的人可能已经穿了一些衣服了。这几件衣服的类中都重写了Show方法,同样也调用了父类的show方法,这样的目的是为了在原先的基础上加上一些新的逻辑,这里的原先是通过调用父类的Show方法实现的,新加的逻辑在我的程序中是输出对应的衣服,你同样可以实现别的逻辑。

下面给出主类:

[java] 
package PersonDecorate; 
 
public class Test { 
 
    /**
     * @param args
     */ 
    public static void main(String[] args) { 
        // TODO Auto-generated method stub 
        Person person = new Person("SuperMan"); 
        System.out.println("第一种:"); 
        //创建三件衣服 
        Sneakers pqx = new Sneakers(); 
        BigTrousers kk = new BigTrousers(); 
        TShirts dtx = new TShirts(); 
         
        pqx.Decorate(person);//这时候的person已经穿上了破球鞋 
        kk.Decorate(pqx);//这时候的person已经穿上了破球鞋、跨裤 
        dtx.Decorate(kk);//这时候的person已经穿上了破球鞋、跨裤、大T恤  
        //这个只是组合的一种,可以随便变换顺序 
        dtx.Show();  
    } 

结果是
[java] 
第一种: 
大T恤 
跨裤 
破球鞋 
装扮的SuperMan 
这里需要注意这些Show方法调用顺序,例如在我们衣服类中Show方法是先输出还是先调用super.Show方法呢,它们的先后也决定了输出的结果。

另外我们同样也可以将Person类做成一个父类,然后再让我们实际穿衣服的人继承它,这样我们就可以给不同的角色的人穿衣服了。

我认为装饰模式主要的就是在装饰类(本程序是服饰类)中存储实际操做的对象,然后在通过子类为其添加一些业务逻辑,这里面类方法的调用顺序是比较混乱,但是如果搞明白了,这个设计模式也就学的比较透彻了。
作者:mengxiangyue

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,