代理模式
代理模式就是,買房子得通過中介,打官司需要請律師,打怪獸找奧特曼。
上代碼:
//一個加法計算器的接口
public interface ICalculator {
public int add(int a, int b);
}
//定義計算器類,實現此接口
public class CalculatorImpl implements ICalculator {
@Override
public int add(int a, int b) {
return a + b;
}
}
//代理類
public class MyProxy implements ICalculator {
ICalculator iCalculator = null;
public MyProxy() {
this.iCalculator = new CalculatorImpl();
}
@Override
public int add(int a, int b) {
//增加代碼,對輸入做一些處理
doSthBefore();
int result = iCalculator.add(a, b);
//增加代碼,對結果做一些處理
doSthAfter();
return result;
}
private void doSthBefore() {
}
private void doSthAfter() {
}
}
//調用代碼
ICalculator iCalculator = new MyProxy();
iCalculator.add(5, 6);
幾個需要注意的點:
- 代理類(MyProxy)與被代理類(CalculatorImpl)要實現同一個接口(ICalculator)
- 代理類包含有被代理類的對象,因為干實事的時候還是要靠這個對象的。
- 代理類可以在被代理類真正“工作”之前和之后做一些必要操作(doSthBefore()和doSthAfter())。
你要買90平的房子,但房源都是60平的戶型,中介是不會通知你看房的,這是doSthBefore();有了90的戶型,但,賣方要價遠遠超出你的報價,中介同樣不會通知你看房的,這就是doSthAfter()。
裝飾模式
裝飾模式通常用來動態的擴展目標的類的功能。
//定義計算器接口
public interface ICalculator {
public int add(int a, int b);
}
//定義計算器接口
public class CalculatorImpl implements ICalculator {
@Override
public int add(int a, int b) {
return a + b;
}
}
//裝飾器
public class MyDecorator implements ICalculator {
ICalculator iCalculator = null;
public MyDecorator(ICalculator iCalculator) {
this.iCalculator = iCalculator;
}
@Override
public int add(int a, int b) {
//增加代碼,對輸入做一些處理
doSthBefore();
int result = iCalculator.add(a, b);
//增加代碼,對結果做一些處理
doSthAfter();
return result;
}
private void doSthBefore() {
}
private void doSthAfter() {
}
}
//調用代碼
ICalculator iCalculatorImpl = new CalculatorImpl();
ICalculator iCalculator = new MyDecorator(iCalculatorImpl);
iCalculator.add(5, 6);
幾個需要注意的點:
- 裝飾類(MyDecorator)與被裝飾類(CalculatorImpl)要實現同一個接口(ICalculator)
- 裝飾類包含有被裝飾類的對象,因為同樣要靠它干實事。
- doSthBefore()和doSthAfter()的作用同上。
區別在哪里
看到這你可能會覺得,代理模式和裝飾模式看起來簡直就像是異父異母的孿生兄弟一樣像,那干嘛分開來講呢?
上面在談到裝飾模式的時候,說到了“動態”——加粗的東西通常能給人以不一樣的感官刺激,很顯然,你并沒有體會過這種感覺——這就是兩者的區別之一。
為了照顧缺乏想象力的童鞋,我們還是以圖片的形式舉例子
E24C.png
把被裝飾類看做一個牛奶加工廠,它只負責包裝。有一天,上級有了新的精神——不是所有的牛奶都叫特輪酥,這就要求升級生產工藝,要對原材料(散裝奶)進行篩選,符合要求的才會被包裝,不符合要求的直接廢棄。
3041.png
圖中兩條紅線就是裝飾者,它使加工廠有了篩選的功能,所以是對原加工廠功能的一種擴展。只要篩選標準一致,我們可以把這個裝飾者加在一個羊奶加工廠上,一個可樂加工廠上等等,不需要篩選時隨時可以撤銷(引用被裝飾類的對象即可),這就是動態。
擴展,是兩種設計模式都能實現的。
動態,裝飾模式更側重一些。
屏蔽,代理模式更側重一些(因為客戶端并不知道MyProxy代理的是誰的功能)。
說白了,兩者的區別就體現在MyProxy和MyDecorator的構造函數上。