zoukankan      html  css  js  c++  java
  • 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();
    		}
    
    	}
    }
    
  • 相关阅读:
    Java中的静态方法
    捕获异常代码
    重载与重写的区别
    继承代码
    Android Studio 快捷键一览
    android两种基本联网方式与一种第三方开源项目的使用
    Android Studio导入github下载的project和module
    SlidingMenu 侧滑菜单的用法
    显示图片的(自定义)吐司Toast
    用volley在Genymotion上获取网页源码
  • 原文地址:https://www.cnblogs.com/kristse/p/decorator.html
Copyright © 2011-2022 走看看