设计模式--Proxy

转自:http://blog.csdn.net/dan_xp/article/details/1820852java

最近一直在看java的设计模式 ,感受印象最深入的就是"面向接口编程",在java中,尽可能多定义接口,由于设计的最重要的目的就是应对各 种变化,而接口自己就是一种变化着的Class的直接反映,经过实现特定接口的各类具体类,达到应对变化的目的,下面以Proxy模式为例:编程

Proxy的模式最主要的目的,原有的类对象因为某种缘由不能访问,须要经过一个新的类来间接地去实现,这个新的类就称为代理类,举个例子说明,老王买/卖鱼的例子
public   class  SellFisher  {
    
public int sellFish() {
        System.out.println(
"my fish is delicious!!");
        
return 10;
    }

}
这是一个具体的卖鱼类,表示鱼10元/斤,若是这个类被用到系统中的时候,系统应对变化的灵活性就会大打折扣,请看以下:
public   class  SellFishSystem  {
    
private SellFisher sellfish;
                     
//...
    public void sellFish() {
        sellfish.sellFish();
    }

}
若是之后鱼的价格变化,或者具体的卖鱼方法发生变化,就必须修改已经有的SellFisher的sellFish()的代码,这个状况
使得系统的可扩展性下降,咱们确定会想到解决方案了,定义一个接口,请看代码:
interface  SellFisher  {
    
int sellFish();
}

public   class  SellFishSystem  {
    
private SellFisher sellfish;
    
public void sellFish() {
        sellfish.sellFish();
    }

}
咱们所作的变化,只是把SellFisher从Class提高到Interface,这个时候好处天然很明显了,这个SellFisher自己就表明
了一种不肯定,变化.你们在作开发的时候,阅读源代码的时候,确定遇到过这种状况,老是跟踪类的对象看代码实现,若是发现了接口变量,就会比较 郁闷,得了解它的具体实现类是什么,这个具体实现类的变化一般就能够应对需求的变化,系以及系统扩展.请看上例子,若是鱼的价格变化,或者具体的卖鱼方法 发生变化,咱们只须要新增长SellFisher的实现,
而没必要修改已有的代码,对此个人理解是对系统来讲, 新增长一个类的代码风险要大大低于对已有类的代码的修改.我以为这个也是设计模式的立足点吧(若是你喜欢修改已有代码,那么设计模式就没有多大意义了)
言归正传,有了上面的知识准备,咱们接上面的例子来解释Proxy的模式就简单多了,好比如今鱼的价格变化,卖鱼的提示也发生变化了,咱们须要一个新的Proxy类来实现
interface  SellFisher {
    
int  sellFish();
}

public   class  ConcreteSellFisher  implements  SellFisher {

    
public   int  sellFish() {
         System.out.println(
" my fish is delicious!! " );
         
return   10 ;
    }

}

public   class  ProxySellFisher  implements  SellFisher {

    
private  SellFisher sell;
    
public  ProxySellFisher(SellFisher sell) {
        
this .sell  =  sell;
    }
    
public   int  sellFish() {
        System.out.println(
" the fish price higher " );
        
return  sell.sellFish() + 10 ;
    }

}
看上面,这个是Proxy模式的代码例子实现,咱们如今在SellFishSystem 使用ProxySellFisher来卖鱼了,由ProxySellFisher再调用原来的ConcreteSellFisher类.具体的一些特征总结为:
1.有个代理类Proxy(和原来的实现类继承同一接口),该类里引用了原来的具体功能实现类(这里是ConcreteSellFisher)
2.重写实现方法,加一些新的变化的元素(好比鱼的价格上涨)
JDK里的Proxy类也实现了这个模式,只不过它叫动态代理,由于它的代理类变成了InvocationHandler了,执行的方法
是invoke了,从而变得更加灵活了,请看代码
public   class  ProxySellFisher  implements  InvocationHandler {

    
private  SellFisher sell;
    
public  ProxySellFisher(SellFisher sell) {
        
this .sell  =  sell;
    }
    
public  Object invoke(Object obj, Method method, Object[] args)  throws  Throwable {
        System.out.println(
" the fish price higher " );
        
return  (Integer)method.invoke(sell, args) + 10 ;
    }

}


public   class  ClientTest {
    
public   static   void  main(String args[]) {
        SellFisher s 
=   new  ConcreteSellFisher();
        InvocationHandler p 
=   new  ProxySellFisher(s);
        Object obj 
=  Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), p);
        ((SellFisher)obj).sellFish();
    }
}
请注意, invoke(Object obj,Method method,Object[] args),这里的第一个参数obj其实能够看做没有用处的,不知道jdk为何要把它也看成一个参数放这里,methd.invoke()方法,须要把 原来的具体实现类做为参数传递进去,method.invoke(obj,args)至关于obj.method(args)
总结,从设计模式的角度讲,你们之后编程中,尽可能要面向接口,更通俗一点就是, 一个类中使用的别的对象成员变量,最好定义成接口的变量而不是实际实现类的变量
相关文章
相关标签/搜索