繼承,裝飾者模式和動態代理之間的區別
阿新 • • 發佈:2019-01-27
Java中,需要對物件進行增強時,我們常用的三種方法是 繼承, 裝飾者模式和動態代理.現在,舉個例子來描述這三者之間的區別.
在星巴克喝咖啡時, 可以選擇各種調味品, 黑咖啡中可以選擇加糖,加奶,加蜂蜜. 這樣咖啡的味道被改變,我們可以說黑咖啡被"增強"了.用java程式碼這樣表示:
/** * 建立一個咖啡的類,裡面有黑咖啡 */ class Coffee{ void blankCoffee(){ System.out.println("黑咖啡"); } } /** * 現在要對黑咖啡加糖 */ class Sugar extends Coffee { void blankCoffee() { super.blankCoffee(); System.out.println("加糖"); } } /** * 現在要對黑咖啡加奶 */ class Milk extends Coffee { void blankCoffee() { super.blankCoffee(); System.out.println("加奶"); } } /** * 現在要對黑咖啡加蜂蜜 */ class Honey extends Coffee { void blankCoffee() { super.blankCoffee(); System.out.println("加蜂蜜"); } }
這樣子我們得到了三種不同口味的黑咖啡. 現在又有了新的問題, 要求要加奶又加糖的咖啡,需要給加奶的咖啡加上糖,用繼承這樣子來實現
/**
* 現在需要加奶加糖咖啡
*/
class SugarMilke extends Milk {
void blankCoffee() {
super.blankCoffee();
System.out.println("加糖");
}
}
...
可能還需要加奶加蜂蜜的咖啡... 多種排列組合就會出現很多類, 出現了新的一種口味又需要增加很多的類.
這時候我們用裝飾者模式來解決這個問題
/** * 首先定義一個介面來規範咖啡. */ interface Coffee { void coffee(); } /* * 實現這個上面這個介面中的方法. */ class CoffeeImpl implements Coffee { public void coffee(){ System.out.println("黑咖啡"); } } /* * 在給黑咖啡新增調味品之前,我們先定義一個類,這個類是所有新增調味品咖啡的父類,進行包裝 */ class CoffeeWrapper implements Coffee { private Coffee cof; public CoffeeWrapper(Coffee cof){ this.cof = cof; } public void coffee(){ cof.coffee(); } } /** * 加糖咖啡 */ class Sugar extends CoffeeWrapper { public Sugar(Coffee cof) { super(cof); } public void coffee(){ super.coffee(); System.out.println("加糖"); } } /** * 加奶咖啡 */ class Milk extends CoffeeWrapper { public Milk(Coffee cof) { super(cof); } public void coffee(){ super.coffee(); System.out.println("加奶"); } } /** * 蜂蜜咖啡 */ class Honey extends CoffeeWrapper { public Honey(Coffee cof) { super(cof); } public void coffee(){ super.coffee(); System.out.println("加蜂蜜"); } }
/**
* 演示
*/
public class Demo() {
public static void main(String[] args) {
//首先建立一個黑咖啡
Coffee cof = new CoffeeImpl();
//加糖咖啡
Coffee sugar = new Sugar(cof);
sugar.coffee();
//加糖又加奶咖啡
Coffee milk = new Milk(sugar);
sugar.coffee();
}
}
這樣我們就解決了這個問題.
* 繼承
被增強的物件固定的
增強的內容也是固定的
* 裝飾者模式
被增強的物件是可以切換的
增強的內容是固定的
還有一種更加靈活的方式,面向切面程式設計(AOP) ,比裝飾者模式更加靈活, 被增強的物件和增強的內容都是可以更換的.