`

结构型模式---装饰模式(Decorator)

阅读更多

一:定义:

Decorator:Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

二:引入

假设现在有一家咖啡店,经营咖啡,茶等饮料,我们来为它设计一个系统。

 

问题:

  • 饮料加糖或牛奶等调料时是要另收费的(每包1元),顾客可以要也可以不要,所以这个固定价格的cost方法不符合要求. 不符合OCP(open for extension,close for modification)

重新设计:

很显然,这种设计也不合适,会导致

  • 类数量爆炸性增长(class exploson).
  • 也不符合要求,比如有的顾客要两包糖等情况没有考虑到.

引入Decorator设计模式:

public abstract class Beverage ...{
    
private String discription;

    
    
public String getDiscription() ...{
        
return discription;
    }


    
public void setDiscription(String discription) ...{
        
this.discription = discription;
    }


    
public abstract double cost() ;
}



public class Coffee extends Beverage...{
    
public Coffee()
    
...{
        setDiscription(
"coffee");
    }

    
public  double cost() 
    
...{
        
return 10;
    }

}



public abstract class CondimentDecorator extends Beverage...{
    
public abstract String getDiscription() ;
}


public class CondimentMilk extends CondimentDecorator...{
    
private Beverage beverage;
    
public CondimentMilk(Beverage beverage)
    
...{
        
this.beverage=beverage;
    }

    
public  double cost() 
    
...{
        
return beverage.cost()+1;
    }

    
public  String getDiscription() 
    
...{
        
return beverage.getDiscription()+",milk";
    }

}



public class Client ...{
    
public static void main(String args[])
    
...{
        Beverage coffee
=new Coffee();
        System.out.println(coffee.getDiscription()
+":"+coffee.cost());
        System.out.println(
new CondimentMilk(coffee).getDiscription()+":"+new CondimentMilk(coffee).cost());
        System.out.println(
new CondimentSugar(new CondimentMilk(coffee)).getDiscription()+":"+new CondimentSugar( new CondimentMilk(coffee)).cost());
        System.out.println(
new CondimentSugar(new CondimentSugar(new CondimentMilk(coffee))).getDiscription()+":"+new CondimentSugar(new CondimentSugar( new CondimentMilk(coffee))).cost());
    }

}



 

三:结构

    

四:实际应用

  1. JAVA I/O  系统是decorator模式的典型应用

 

我们自己来写一个InputStream decorator,用来使所有的输出字符变成小写.

public class LowerCaseInputStream extends FilterInputStream ...{

    
protected LowerCaseInputStream(InputStream in) ...{
        
super(in);
    }

    
    
public  int read() throws IOException
    
...{
        
int c=super.read();
        
return (c==-1?c:Character.toLowerCase(c));
    }

}


public class IoTest ...{
    
public static void main(String args[]) ...{
        
int c;
        String filePath 
= "f:/temp/designPatten.txt";
        
try ...{
            InputStream in 
= new LowerCaseInputStream(new BufferedInputStream(new FileInputStream(
                    filePath)));
            
while(( c=in.read())!=-1)
            
...{
                System.out.print((
char)c);
            }

            in.close();

        }
 catch (FileNotFoundException e) ...{

            e.printStackTrace();
        }
 catch (IOException e) ...{

            e.printStackTrace();
        }

    }

}

五:适用情形

Use Decorator

  • to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects.  
  • for responsibilities that can be withdrawn.
  • when extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing.

参考文献:
1:阎宏,《Java与模式》,电子工业出版社
2:Eric Freeman & Elisabeth Freeman,《Head First Design Pattern》,O'REILLY

     

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics