装饰者模式 : 动态的将责任附加在对象之上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案 。
在这个设计模式 首先你要搞清楚 什么是装饰者,什么是被装饰者。 看下面的例子,你去星巴克喝咖啡 你可以在点了拿铁咖啡之后,你还想往里面加入奶昔,牛奶,方糖等。
那么 此时的 奶昔,牛奶,以及方糖就是 装饰,用来装饰咖啡的,那个 咖啡就是被装饰者。
现有如下 需求场景 : 星巴克 有各种饮料,比如 咖啡,橙汁,绿茶等,还有许多的调料 比如牛奶,方糖,奶昔等,而这些调料是需要收费的, 饮料和调料可以互相整合, 等会好之后一起打印出来 用户点了那些东西,以及计算出总价钱。
由于装饰者和被装饰者是可以互相整合的,那么他们必须是相同的 “类型”, 这里使用的集成并不是为了在程序运行的时候表现出相应的行为,而只是为了类型上面的匹配。 看如下的 UMl 图:
从图中 可以知道 Beverage (饮料) 是被装饰者,它是个父类,有具体的被装饰者 : 橙汁,绿茶,咖啡
还有 一个调料类 Condiment 类, 它下面的是具体的 装饰者 具体的是 Milk,Mocha,Whip , 装饰者和被装饰者都有相同的父类,以保证他们可以互相整合。
具体的实现代码 如下:
先写被装饰者:
package com.beizhuangshi.www;
public abstract class Beverage
{
public String descrption;
public String getDescrption()
{
return descrption;
}
public abstract double cost();
}
//具体的被装饰者
package com.beizhuangshi.www;
/** */
public class Tea extends Beverage
{
/** */
public Tea()
{
descrption = " Tea";
}
/** */
public double cost()
{
return 3.0;
}
}
package com.beizhuangshi.www;
/** */
public class OrangeJuice extends Beverage
{
/** */
public double cost()
{
return 2.0;
}
/** */
public OrangeJuice()
{
descrption ="OrangeJuice";
}
}
package com.beizhuangshi.www;
/** */
public class Coffe extends Beverage
{
/** */
public Coffe()
{
descrption = "Coffe";
}
public double cost()
{
return 1.0;
}
}
//下面实现装饰者
package com.zhuangshizhe.www;
import com.beizhuangshi.www.Beverage;
/** */
public abstract class Condiment extends Beverage
{
public abstract String getDescrption();
}
package com.zhuangshizhe.www;
import com.beizhuangshi.www.Beverage;
/** */
public class Milk extends Condiment
{
/** */
public Beverage beverage;
public Milk(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescrption()
{
return beverage.getDescrption() + " Milk" ;
}
/** */
@Override
public double cost()
{
return beverage.cost() + 4.0;
}
}
package com.zhuangshizhe.www;
import com.beizhuangshi.www.Beverage;
/** */
public class Mocha extends Condiment
{
public Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescrption()
{
return beverage.getDescrption() + " Mocha " ;
}
/** */
@Override
public double cost()
{
return beverage.cost() + 5.02;
}
}
package com.zhuangshizhe.www;
import com.beizhuangshi.www.Beverage;
/** */
public class Whip extends Condiment
{
/** */
public Beverage beverage;
public Whip(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescrption()
{
return beverage.getDescrption() + " Whip " ;
}
/** */
@Override
public double cost()
{
return beverage.cost() + 6.02;
}
}
//测试一下
package com.zhuangshizhe.test.www;
import com.beizhuangshi.www.Beverage;
import com.beizhuangshi.www.Tea;
import com.zhuangshizhe.www.Milk;
public class Test {
public static void main(String[] args){
Beverage teaBeverage = new Tea();
System.out.println(teaBeverage.getDescrption() + " Cost" + teaBeverage.cost());
teaBeverage = new Milk(teaBeverage);
teaBeverage= new Milk(teaBeverage);
System.out.println(teaBeverage.getDescrption() + " Cost" + teaBeverage.cost());
}
}
看看下面的java.io 这里面的 FileReader ,BufferedReader 全是装饰者
package com.fileReader.www;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStream;
public class FileReaderTest {
public static void main(String[] args){
File f = new File("D://PassWord.txt");
FileReader fr = null;
BufferedReader buf = null;
try {
fr = new FileReader(f);
buf = new BufferedReader(fr);
String context = null;
while((context = buf.readLine())!=null){
System.out.println(context);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try{
if(fr!=null){
fr.close();
}
if(buf!= null){
buf.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}