JAVA设计模式学习笔记-装饰者模式

较差的方案

每个单品都是一个子类,根据策略模式,众多单品子类都有的共同点,抽象出一个父类抽象类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();
		}

	}
}
posted @ 2020-02-02 14:04  KrisTse  阅读(127)  评论(0编辑  收藏  举报