案例:
咖啡馆订单:
1)、咖啡种类:Espresso、ShortBlack、LongBlack、Decaf
2)、调料:Milk、Soy、Chocolate
3)、扩展性好、改动方便、维护方便
类图:
关键代码:
装饰者模式下的订单:2份巧克力+一份牛奶的LongBlack
1. Component
package CoffeeBar.AbstractSuperClass;
public abstract class Drink
{
public String description="";
private float price=0.f;
public abstract float cost();
public String getDescription()
{
return description+"-"+getPrice();
}
public void setDescription(String description)
{
this.description = description;
}
public float getPrice()
{
return price;
}
public void setPrice(float price)
{
this.price = price;
}
}
2. ConcreteComponent
package CoffeeBar.ConcreteComponent;
import CoffeeBar.AbstractSuperClass.Drink;
public class Coffee extends Drink
{
@Override
public float cost()
{
return super.getPrice();
}
}
package CoffeeBar.ConcreteComponent;
public class LongBlack extends Coffee
{
public LongBlack()
{
super.setDescription("LongBlack");
super.setPrice(6.0f);
System.out.println("LongBlack,6.0");
}
}
3. Decorator
package CoffeeBar.Decorator;
import CoffeeBar.AbstractSuperClass.Drink;
public class Decorator extends Drink
{
private Drink obj;
public Decorator(Drink obj)
{
this.obj=obj;
}
@Override
public float cost()
{
System.out.println("obj.getPrice()"+obj.getPrice());
System.out.println("super.getPrice()"+super.getPrice());
return super.getPrice()+obj.cost();
}
@Override
public String getDescription()
{
return super.description+super.getPrice()+"&&"+obj.getDescription();
}
}
4. ConcreteDecorator:
package CoffeeBar.Decorator;
import CoffeeBar.AbstractSuperClass.Drink;
public class Milk extends Decorator
{
public Milk(Drink obj)
{
super(obj);
super.setDescription("Milk");
super.setPrice(2.0f);
}
}
5. 入口
order=new LongBlack();
order=new Milk(order);
order=new Chocolate(order);
order=new Chocolate(order);
System.out.println("price:"+order.cost());
System.out.println("desc:"+order.getDescription());
装饰器模式原理:
实际应用案例
java 的IO流
自定义一个转大写的ConcoreateDecorator
package myjavaIO;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public class UpperCaseInputStream extends FilterInputStream
{
protected UpperCaseInputStream(InputStream in)
{
super(in);
}
public int read() throws IOException
{
int c=super.read();
return c==-1?c:Character.toUpperCase((char)c);
}
public int read(byte[] b,int offset,int len) throws IOException
{
int result=super.read(b, offset, len);
for (int i = 0; i < result; i++)
{
b[i]=(byte)Character.toUpperCase((char)b[i]);
}
return result;
}
}
并测试之
package myjavaIO;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
public class InputTest
{
public static void main(String[] args)
{
int c;
InputStream inputStream;
try
{
inputStream = new UpperCaseInputStream(new BufferedInputStream(
new FileInputStream("test.txt")));
while((c=inputStream.read())>=0)
{
System.out.print((char)c);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}