努力,成长,提高

在追求中进步
数据加载中……
decorator装饰模式的一种改进写法
倘若,有这么一个需求,对于一个数字,如果是负的,那么需要变成正的相反数,如果是2的倍数,那么就除以2,如果是3的倍数,那么就除以3,可能以后还有其他的需求,比如是5的倍数,就再除以5,或者是6的倍数,那么就加上6,也就是结果与顺序息息相关,那么应该如何来实现呢?
如果写一个类的方法,按照这个需求来写if语句,可以,但是,如果有两套定制的呢?一套需要其中的几种变化,另外需要另外几种,那么就需要2个方法,而且其中有很多的重复代码,这样行不通的.
其实设计模式说到底,其根本思想就是找到变化并封装之.这里变化的是处理的方法,那么我们就把它封装起来.实现的类如下:

package decorater;

public class Integor {
    
private Integer x;

    
public Integer getX() {
        
return x;
    }

    
public void setX(Integer x) {
        
this.x = x;
    }
    Integor(Integer x){
        
this.x = x;
    }
}
由于Integer不能修改传递的值,所以写一个类来封装一个integer

/**
 * 
 
*/
package decorater;

public abstract class Decorater {
    
private Decorater next;

    
public Decorater setNext(Decorater dcrtr) {
        
this.next = dcrtr;
        
return this.next;
    }

    
public void process(Integor x) {
        
this.executeBefore(x);
        
if (this.next != null) {
            
this.next.process(x);
        }
        
this.executeAfter(x);
    }

    
protected abstract void executeBefore(Object x);

    
protected abstract void executeAfter(Object x);

}
每个实现的类只需要来实现executeBefore和executeAfter方法即可.
注意实现的顺序是
decorater1.executeBefore->decorater2.executeBefore->decorater3.executeBefore->decorater3.executeAfter->decorater2.executeAfter->decorater1.executerAfter

package decorater;

public class PositiveDecorater extends Decorater {

    @Override
    
protected void executeAfter(Object x) {

        System.out.println(
"PositiveDecorater end!");
    }

    @Override
    
protected void executeBefore(Object x) {
        
// TODO Auto-generated method stub

        System.out.println(
"starting PositiveDecorater!");
        Integor in 
= (Integor) x;
        
if (in.getX() < 0)
            in.setX(
-in.getX());
    }

}

package decorater;

public class Devide2Decorater extends Decorater {

    @Override
    
protected void executeAfter(Object x) {
        System.out.println(
"Devide2Decorater end!");

    }

    @Override
    
protected void executeBefore(Object x) {
        System.out.println(
"Starting Devide2Decorater!");
        Integor in 
= (Integor) x;
        
if (in.getX() % 2 == 0) {
            in.setX(in.getX() 
/ 2);
        }

    }

}

package decorater;

public class Devide3Decorater extends Decorater {

    @Override
    
protected void executeAfter(Object x) {
        System.out.println(
"Devide3Decorater end!");
    }

    @Override
    
protected void executeBefore(Object x) {

        System.out.println(
"Starting Devide3Decorater!");
        Integor in 
= (Integor) x;
        
if (in.getX() % 3 == 0) {
            in.setX(in.getX() 
/ 3);
        }

    }

}

/**
 * 
 
*/
package decorater;

/**
 * 
@author KONGHE
 * 
 
*/
public class Main {

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        Decorater a 
= new PositiveDecorater();
        a.setNext(
new Devide2Decorater()).setNext(new Devide3Decorater());
        Integor x 
= new Integor(-18);
        a.process(x);
        System.out.println(x.getX());

    }

}

输出结果是:
starting PositiveDecorater!
Starting Devide2Decorater!
Starting Devide3Decorater!
Devide3Decorater end!
Devide2Decorater end!
PositiveDecorater end!
3

其实每种设计模式的核心思想都是一致的,但是没有必要照本宣科,只要注意其模式的精髓,就可以了,剩下的就是自己去按照实现来设计其中的细节了.比如我设计这个模式,就是先写了main函数,把其中的方法写好,然后去按照这个实现来想去如何实现,这样才更符合解决实际的问题.其实decorater模式有很多种实现方式.比如下面的这种解法,也可:

/**
 * 
 
*/
package decorator;

/**
 * 
@author KONGHE
 * 
 
*/
public class Main {

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        DecoraterChain a 
= new DecoraterChain();
        a.setNext(
new PositiveDecorater()).setNext(new Devide2Decorater()).setNext(new Devide3Decorater());
        Integer x 
= -32;
        x 
= a.process(x);
        System.out.println(x);

    }

}

/**
 * 
 
*/
package decorator;

import java.util.ArrayList;
import java.util.List;

/**
 * 
@author KONGHE
 * 
 
*/
public class DecoraterChain {
    
private List<Decorater> decorater = new ArrayList<Decorater>();

    
public DecoraterChain setNext(Decorater decrter) {
        decorater.add(decrter);
        
return this;
    }

    
public Integer process(Integer x) {
        
for (int i = 0; i < this.decorater.size(); i++) {
            x 
= this.decorater.get(i).process(x);
        }
        
return x;
    }

}

/**
 * 
 
*/
package decorator;


/**
 * 
@author KONGHE
 * 
 
*/
public abstract class Decorater {
    
public abstract Integer process(Integer x);

}


总而言之,模式是为了具体的实际情况而服务的,不要为了一定要去用某种设计模式而委屈自己的需求.
在设计的时候多想想,可能某天你再读设计模式的书,你会发现,原来我之前写的代码,包含了这么多的设计模式啊!




posted on 2009-05-22 17:20 孔阳 阅读(1361) 评论(3)  编辑  收藏

评论

# re: decorator装饰模式的一种改进写法 2009-05-22 19:32 杰德。张

学以致用才是硬道理。。。学习了。。
  回复  更多评论    

# re: decorator装饰模式的一种改进写法 2013-04-10 09:18 dohkoos

不是起个Decorator类名就叫Decorator模式的,你的这个实现明显是Strategy模式的变形。
  回复  更多评论    

# re: decorator装饰模式的一种改进写法 2013-04-21 11:39 孔阳

@dohkoos
其实,用多了心中无模式才是最终的模式.
与其讨论是什么设计模式,倒不如考虑, 某种实现是否真正的满足了需求.
  回复  更多评论    

只有注册用户登录后才能发表评论。


网站导航: