先看例子:
package com.zq.designpattern.proxy;
/**
* Created by zhengshouzi on 2015/10/29.
*/
public class ProxyPattern {
public static void main(String[] args) {
//三聚氰胺..........於是奶粉代購火了
// 但是不是每個人都有空隨時去德國(這就可以看成是遠程代理)
// 當然德國的奶粉生產商也不可以能直接和每個想買奶粉的人打交道,他說我只賣給代理商(這可以看成是保護代理,控制應用對象具有不同的訪問權限)
// 這時候朋友圈裏面跳出來來一個奶粉代購妹妹,
//奶粉原價是100,但是代理價200,代理給你加價了,這就是在一個代理對象前後執行了附加的操作(這可以看成是智能指引代理,他在訪問前後執行了附加操作)</span></span>
MilkProxy milkProxy = new MilkProxy();
//張三準備賣5罐奶粉
milkProxy.sell(5);
//李四買10罐
milkProxy.sell(10);
//王五買20罐
milkProxy.sell(20);
System.out.println("代購收益:"+milkProxy.computeProfit());
}
}
interface Milk{
void sell(int number);
}
class Manufacturer implements Milk{
private int number=2000;
private String name;
private int price;
private int saledCount=0;
public int getPrice() {
return price;
}
public Manufacturer(){
name = "牛奶";
price = 100;
}
public void sell(int number) {
System.out.println("生產商賣 "+number+" 罐奶粉給代購");
saledCount +=number;
}
}
class MilkProxy implements Milk{
//代理知道生產商上哪兒找生產商,
Manufacturer manufacturer = new Manufacturer();
private int price=0;
private int saledCount=0;
private long profit=0;
private int size=0;
public MilkProxy(){
this.price=200;
}
@Override
public void sell(int number) {
size +=number;
while(size>20){
//打開下面的註釋這樣寫表示當你能夠靠賣奶粉賺到錢的時候(只買1兩件,代理商怎麼願意跑一趟德國嘛),代理商才真正的去找生產商(可以看成是虛代理)
//manufacturer = new Manufacturer();</span></span>
System.out.println("去拿貨");
//實際上他是在幫生產商賣牛奶,然後自己賺差價
manufacturer.sell(size);
System.out.println("代購賣 " + size + " 罐奶粉給客戶");
saledCount+=size;
size=0;
}
}
public long computeProfit(){
profit = saledCount*(price-manufacturer.getPrice());
return profit;
}
}
通過這個例子,我像你明白什麼是代理模式了吧。
代理模式
代理模式的作用是:爲其他對象提供一種代理以控制對這個對象的訪問。
在某些情況下,一個客戶不想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。
代理模式一般涉及到的角色
抽象角色:聲明真實對象和代理對象的共同接口(例子裏的牛奶接口)。
代理角色:代理對象角色內部含有對真實對象的引用,從而可以操作真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能夠代替真實對象(代理商)。
同時,代理對象可以在執行真實對象操作時,附加其他的操作,相當於對真實對象進行封裝。
真實角色:代理角色所代表的真實對象,是我們最終要引用的對象(生產商)。
問題
如果要按照上述的方式(靜態代理)使用代理模式,那麼真實角色必須是實現已經存在的,並將其作爲代理對象的內部屬性。
但是實際使用時,一個真實角色必須對應一個代理角色,但如果大量使用會導致類的急劇膨脹;此外,如果事先並不知道真實角色,該如何使用代理呢?這個問題可以通過Java的動態代理類來解決。