较差的方案
每个单品都是一个子类,根据策略模式,众多单品子类都有的共同点,抽象出一个父类抽象类Drink,每当有一个新品出现都要写一个单品类,不易扩展,会产生很多子类,臃肿
更好一些的方案
将所有调料集成到父类 属性,并给出相应判断是否添加调料 方法
可用switch,0(不加),1(加),确定添加哪些调料
不会出现类爆炸,产生很多子类,但是当调料种类,数量增加时,扩展性就很差,需要不停得修改父类
装饰者模式方案
Component 主体(父类抽象类)
ConcreteComponent 具体主体(子类)
Decorator 装饰者
装饰者模式:动态得将新功能添加到对象上,在对象功能扩展方面,它比继承更有弹性
Drink类
所有coffee的父类
package com.java.test.coffeebar;
public abstract class Drink {
public String description="";
private float price=0f;;
public void setDescription(String description)
{
this.description=description;
}
public String getDescription()
{
return description+"-"+this.getPrice();
}
public float getPrice()
{
return price;
}
public void setPrice(float price)
{
this.price=price;
}
public abstract float cost();
}
Coffee
package com.java.test.coffeebar.coffee;
import com.java.test.coffeebar.Drink;
public class Coffee extends Drink {
@Override
public float cost() {
// TODO Auto-generated method stub
return super.getPrice();
}
}
一种咖啡
Decaf
package com.java.test.coffeebar.coffee;
public class Decaf extends Coffee {
public Decaf()
{
super.setDescription("Decaf");
super.setPrice(3.0f);
}
}
另一种咖啡
Espresso
package com.java.test.coffeebar.coffee;
public class Espresso extends Coffee{
public Espresso()
{
super.setDescription("Espresso");
super.setPrice(4.0f);
}
}
调料
Decorator
package com.java.test.coffeebar.decorator;
import com.java.test.coffeebar.Drink;
public class Decorator extends Drink {
private Drink Obj;
public Decorator(Drink Obj){
this.Obj=Obj;
};
@Override
public float cost() {
// TODO Auto-generated method stub
return super.getPrice()+Obj.cost();
}
@Override
public String getDescription()
{
return super.description+"-"+super.getPrice()+"&&"+Obj.getDescription();
}
}
一种调料
Chocolate
package com.java.test.coffeebar.decorator;
import com.java.test.coffeebar.Drink;
public class Chocolate extends Decorator {
public Chocolate(Drink Obj) {
super(Obj);
// TODO Auto-generated constructor stub
super.setDescription("Chocolate");
super.setPrice(3.0f);
}
}
另一种调料
Milk
package com.java.test.coffeebar.decorator;
import com.java.test.coffeebar.Drink;
public class Milk extends Decorator {
public Milk(Drink Obj) {
super(Obj);
// TODO Auto-generated constructor stub
super.setDescription("Milk");
super.setPrice(2.0f);
}
}
测试类
package com.java.test.coffeebar;
import com.java.test.coffeebar.coffee.Decaf;
import com.java.test.coffeebar.coffee.LongBlack;
import com.java.test.coffeebar.decorator.Chocolate;
import com.java.test.coffeebar.decorator.Milk;
public class CoffeeBar {
public static void main(String[] args) {
Drink order;
order=new Decaf();
System.out.println("order1 price:"+order.cost());
System.out.println("order1 desc:"+order.getDescription());
System.out.println("****************");
order=new LongBlack();
//这里是精髓
//一层又一层包装
order=new Milk(order);
order=new Chocolate(order);
order=new Chocolate(order);
System.out.println("order2 price:"+order.cost());
System.out.println("order2 desc:"+order.getDescription());
}
}
精髓在于,调料里面都要new出一个coffee,一层又一层的包装
Java内置类的装饰者模式
看不懂
UpperCaseInputStream
package com.java.test.myiodecorator;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
//把小写变成大写
public class UpperCaseInputStream extends FilterInputStream{
protected UpperCaseInputStream(InputStream in) {
super(in);
// TODO Auto-generated constructor stub
}
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;
}
}
InputTest
package com.java.test.myiodecorator;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class InputTest {
public static void main(String[] args) {
int c;
try {
InputStream in = new UpperCaseInputStream(new BufferedInputStream(
new FileInputStream("F:\test.txt")));
while((c=in.read())>=0)
{
System.out.print((char)c);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}