风言枫语  

看到字眼,你应该心里有个数了,所谓装饰,就是在原有的基础上加些东西化化装,有修睫毛的,有化口红的,有时尚的衣服等等,然后呢就 变漂亮了;比如礼品,都要加个礼品

盒,然后档次提高了,可以开个好价 ,这也是“装饰”。


装饰者模式有个 需要遵循的原则:开闭原则,即对修改关闭,对扩展开放。


什么情况下需要用到装饰装者模式? 我的理解就是:当我已经提供了一些method,而你要使用我的method,那么你只能在不损坏我的method 的前提下,在我的method的基础


上 进行扩展,也就是覆盖处理。


使用装饰者模式有什么好处?  就是不损坏需要装饰的类,也即保护需要装饰的类。


实例代码:


beverage.java

 

public abstract class Beverage{
        String description="Unknown Beverage";
        String size="medium";
	public String getDescription(){
	     return description;
	}
	
	public abstract double cost();
	
	public String getSize(){
	   return size;
	}
    
	public void setSize(String size_){
	    this.size=size_;
	}
}

 


CondimentDecorator.java

public abstract class CondimentDecorator extends Beverage{
    public abstract String getDescription();

}


Espresso.java

public class Espresso extends Beverage{
  
    public Espresso(){
	 description="Espresso";
    }
    
    public double cost(){
	 return 1.99;
    }
}


HouseBlend.java

public class HouseBlend extends Beverage{

    public HouseBlend(){
	   description="HouseBlend";
	}
    
	public double cost(){
	  
	     return 0.89;
    }
}


DarkRoast.java

public class DarkRoast extends Beverage{
 
    public DarkRoast(){
	
	   description="DarkRoast";
	}
    
	public double cost(){
	   return 0.99;
	}
}


Mocha.java

public class Mocha extends CondimentDecorator{
        Beverage beverage;
	
	public Mocha(Beverage beverage){
	   this.beverage=beverage;
	}
	
	public String getDescription(){
	    return beverage.getDescription()+",Mocha";
	}
	
	public double cost(){
	   return 0.2+beverage.cost();
	}
}


Soy.java

public class Soy extends CondimentDecorator{
       Beverage beverage;
	
	public Soy(Beverage beverage){
	   this.beverage=beverage;
	}
	
	public String getDescription(){
	    return beverage.getDescription()+",Soy";
	}
	
	public double cost(){
	   return 0.15+beverage.cost();
	}
}


Whip.java

public class Whip extends CondimentDecorator{
       Beverage beverage;
	
	public Whip(Beverage beverage){
	   this.beverage=beverage;
	}
	
	public String getDescription(){
	    return beverage.getDescription()+",Whip";
	}
	
	public double cost(){
	   return 0.10+beverage.cost();
	}
}


BeverageSize.java

public class BeverageSize extends CondimentDecorator{
        public double size=0;
	public Beverage beverage;

	
	public BeverageSize(Beverage beverage){
	   this.beverage=beverage;
	}
	
	public String getDescription(){
	    return beverage.getDescription()+","+beverage.getSize();
	}
	
	
	public double cost(){
	    switch(beverage.getSize()){
		  case "small":
		        return 0.10+beverage.cost();
		  case "medium":
			return 0.15+beverage.cost();
		  case "big":
		        return 0.20+beverage.cost();
		  default:
		        return 0.15+beverage.cost();
		
		
	    }

	}
}


StarBuzzCoffee.java

public class StarBuzzCoffee{
    public static void main(String args[]){
            Beverage beverage = new Espresso();
	    
	    System.out.println(beverage.getDescription()+'$'+beverage.cost());
	   

		 
	    Beverage  beverage2 = new DarkRoast();
            beverage2 = new Mocha(beverage2);
            beverage2 = new Mocha(beverage2);
            beverage2 = new Whip(beverage2);
	    beverage2.setSize("big");
	    beverage2 = new BeverageSize(beverage2); 
		
            System.out.println(beverage2.getDescription()+'$'+beverage2.cost());
		
	    Beverage  beverage3 = new HouseBlend();
            beverage3 = new Mocha(beverage3);
            beverage3 = new Mocha(beverage3);
            beverage3 = new Whip(beverage3);
	    beverage3 = new BeverageSize(beverage3);
            System.out.println(beverage3.getDescription()+'$'+beverage3.cost());
    }
}

 

对应StarBuzzCoffee.java文件,里面的装饰类采用了很多new的方法,优化的方法就是使用工厂方法,所谓工厂也就是生产具体实例的地方;工厂方法有区别于抽象工厂。


有关抽象的概念,比如说抽象类和接口,抽象类里面的方法可以有具体的实现,但是抽象类里面可以有自己的具体实现的方法;而接口只能在其继承类的里面实现方法细节(必须实现)。两者共同的地方就是 继承的类有公共的 方法,既然有共同的方法,就提取出来,做成接口(抽象类)。


下面举例说明下   针对接口编程,不针对实现编程 的原则 :


animals.java

 

interface animals {
    public  void bark();
}

 


cat.java

class cat implements animals {
   public void bark() {
      System.out.println("miao miao");
   }
}


dog.java

class dog implements animals {
    public void bark() {
      System.out.println("wang wang");
   }
}


test.java

public class test{
    public static void main(String args[]) {
       animals a = new dog();
       a.bark();
  }
}


dog,cat都有一个bark的方法,把这个方法提取出来作为一个接口声明。比如说电脑的打印机,电脑提供了USB接口,不论任何打印机只要实现了这个接口,就可以进行打印了,具体怎么实现的,那是打印机厂家的事情了。

如果现在需要cat的bark方法,那么只需要把animals a = new dog();改成 animals a = new cat();即可。如果是针对实现编程 ,那么就是 dog a = new dog(); cat a = new cat();




 

posted on 2013-09-17 23:55  风言枫语  阅读(271)  评论(0编辑  收藏  举报