• 设计模式(装饰者模式)


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

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


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


    什么情况下需要用到装饰装者模式? 我的理解就是:当我已经提供了一些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();




  • 相关阅读:
    高性能队列设计
    线上 RTT 有 1/3 概率超过 3 秒,我用 arthas 查出元凶!
    你管这破玩意儿叫 token
    高可用与Zookeeper设计原理
    从应用层到网络层排查 Dubbo 接口超时全记录
    我是如何晋升专家岗的
    百亿数据,毫秒级返回,如何设计?--浅谈实时索引构建之道
    微信的原创保护机制到底是如何实现的
    AOP面试造火箭始末
    与一位转行做滴滴司机的前程序员对话引发的思考
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3327686.html
Copyright © 2020-2023  润新知