天天看小說

第205章

通過例子告訴大家一點:任何設計不是一成不變的、模式的應用是極其靈活的……

大B:“裝飾模式:Decorator?!”环g成‘裝飾’,我覺得翻譯成‘油漆工’更形象點,油漆工(decorator)是用來刷油漆的,那麼被刷油漆的對象我們稱decoratee。這兩種實體在Decorator模式中是必須的?!?

小A:“那我們應該如何去定義它?”

大B:“動態給一個對象添加一些額外的職責,就象在牆上刷油漆。使用Decorator模式相比用生成子類方式達到功能的擴充顯得更爲靈活?!?

下面是以上各個類的意義:

1、Ingredient(成分):所有類的父類,包括它們共有的方法,一般爲抽象類且方法都有默認的實現,也可以爲接口。它有Bread和Decorator兩個子類。這種實際不存在的,系統需要的抽象類僅僅表示一個概念,2、Bread(麪包):就是我們三明治中必須的兩片面包。它是系統中最基本的元素,也是被裝飾的元素,和IO中的媒質流(原始流)一個意義。在裝飾器模式中屬於一類角色,所以其顏色爲紫色。

3、Decorator(裝飾器):所有其它成分的父類,這些成分可以是豬肉、羊肉、青菜、芹菜。這也是一個實際不存在的類,僅僅表示一個概念,即具有裝飾功能的所有對象的父類。

4、Pork(豬肉):具體的一個成分,不過它作爲裝飾成分和麪包搭配。

5、Mutton(羊肉):同上。

6、Celery(芹菜):同上。

7、Greengrocery(青菜):同上。

大B:“我們現在來總結一下裝飾器模式中的四種角色:1、被裝飾對象(Bread);2、裝飾對象(四種);3、裝飾器(Decorator);4、公共接口或抽象類(Ingredient)。其中1和2是系統或者實際存在的,3和4是實現裝飾功能需要的抽象類。寫段代碼體會其威力!程序很簡單,但是實現的方法中可以加入你需要的方法,意境慢慢體會吧!”

//Ingredient.java

publicabstractclassIngredient{

publicabstractStringgetDescription();

publicabstractdoublegetCost();

publicvoidprintDescription(){

System.out.println(“Name”+this.getDescription());

System.out.println(“PriceRMB”+this.getCost());

}

}

大B:“所有成分的父類,抽象類有一個描述自己的方法和一個得到價格的方法,以及一個打印自身描述和價格的方法?!?

小A:“這個方法不就是與剛纔的那兩個方法構成模板方法嗎?”

//Bread.java

publicclassBreadextendsIngredient{

privateStringdescription;

publicBread(Stringdesc){

this.description=desc;

}

publicStringgetDescription(){

returndescription;

}

publicdoublegetCost(){

return2.48;

}

}

大B:“麪包類,因爲它是一個具體的成份,因此實現父類的所有的抽象方法。描述可以通過構造器傳入,也可以通過set方法傳入。同樣價格也是一樣的,就很簡單地返回了?!?

//Decorator.java

publicabstractclassDecoratorextendsIngredient{

Ingredientingredient;

publicDecorator(Ingredientigd){

this.ingredient=igd;

}

publicabstractStringgetDescription();

publicabstractdoublegetCost();

}

大B:“裝飾器對象,所有具體裝飾器對象父類。它最經典的特徵就是:1、必須有一個它自己的父類爲自己的成員變量;2、必須繼承公共父類。這是因爲裝飾器也是一種成份,只不過是那些具體具有裝飾功能的成份的公共抽象罷了。在我們的例子中就是有一個Ingredient作爲其成員變量。Decorator繼承了Ingredient類?!?

//Pork.java

publicclassPorkextendsDecorator{

publicPork(Ingredientigd){

super(igd);

}

publicStringgetDescription(){

Stringbase=ingredient.getDescription();

returnbase+“\n”+“DecrocatedwithPork!”;

}

publicdoublegetCost(){

doublebasePrice=ingredient.getCost();

doubleporkPrice=1.8;

returnbasePrice+porkPrice;

}

}

大B:“具體的豬肉成份,同時也是一個具體的裝飾器,因此它繼承了Decorator類。豬肉裝飾器裝飾可以所有的其他對象,因此通過構造器傳入一個Ingredient的實例,程序中調用了父類的構造方法,主要父類實現了這樣的邏輯關係。同樣因爲方法是具體的成份,所以getDescription得到了實現,不過由於它是具有裝飾功能的成份,因此它的描述包含了被裝飾成份的描述和自身的描述。價格也是一樣的。價格放回的格式被裝飾成份與豬肉成份的種價格哦!”

大B:“從剛纔的兩個方法中我們可以看出,豬肉裝飾器的功能得到了增強,它不僅僅有自己的描述和價格,還包含被裝飾成份的描述和價格。主要是因爲被裝飾成份是它的成員變量,因此可以任意調用它們的方法,同時可以增加自己的額外的共同,這樣就增強了原來成份的功能。”

//Mutton.java

publicclassMuttonextendsDecorator{

publicMutton(Ingredientigd){

super(igd);

}

publicStringgetDescription(){

Stringbase=ingredient.getDescription();

returnbase+“\n”+“DecrocatedwithMutton!”;

}

publicdoublegetCost(){

doublebasePrice=ingredient.getCost();

doublemuttonPrice=2.3;

returnbasePrice+muttonPrice;

}

}

羊肉的包裝器。

//Celery.java

publicclassCeleryextendsDecorator{

publicCelery(Ingredientigd){

super(igd);

}

publicStringgetDescription(){

Stringbase=ingredient.getDescription();

returnbase+“\n”+“DecrocatedwithCelery!”;

}

publicdoublegetCost(){

doublebasePrice=ingredient.getCost();

doubleceleryPrice=0.6;

returnbasePrice+celeryPrice;

}

}

芹菜的包裝器。

//GreenGrocery.java

publicclassGreenGroceryextendsDecorator{

publicGreenGrocery(Ingredientigd){

super(igd);

}

publicStringgetDescription(){

Stringbase=ingredient.getDescription();

returnbase+“\n”+“DecrocatedwithGreenGrocery!”;

}

publicdoublegetCost(){

doublebasePrice=ingredient.getCost();

doublegreenGroceryPrice=0.4;

returnbasePrice+greenGroceryPrice;

}

}

青菜的包裝器。

大B:“我們來領略裝飾器模式的神奇吧!我們有一個測試類,其中建立夾羊肉的三明治、全蔬菜的三明治、全葷的三明治?!?

小A:“好像真的很香哦!”

publicclassDecoratorTest{

publicstaticvoidmain(String[]args){

Ingredientpound=newMutton(newCelery(newBread(“Master24sBread”)));

pound.printDescription();

pound=newCelery(newGreenGrocery(newBread(“Breadwithmilk”)));

pound.printDescription();

pound=newMutton(newPork(newBread(“Breadwithcheese”)));

pound.printDescription();

}

}

大B:“這就是一個簡單的裝飾器類!假如你對想中國式的吃法,可以將加入饅頭、春捲皮、蛋皮……夾菜可以爲肉絲……突然想到了京醬肉絲。”

第225章第62章第227章第151章第11章第53章第220章第54章第190章第204章第200章第124章第220章第41章第118章第77章第76章第167章第51章第158章第95章第222章第83章第32章第194章第205章第158章第113章第59章第138章第223章第64章第192章第40章第142章第111章第168章第101章第37章第28章第15章第205章第171章第98章第177章第153章第88章第94章第103章第40章第30章第209章第34章第107章第192章第199章第14章第211章第206章第117章第167章第75章第140章第27章第214章第177章第89章第1章第148章第173章第139章第105章第226章第137章第165章第24章第126章第93章第220章第129章第55章第177章第173章第7章第105章第161章第209章第26章第73章第79章第162章第196章第196章第72章第41章第131章第181章第222章第199章
第225章第62章第227章第151章第11章第53章第220章第54章第190章第204章第200章第124章第220章第41章第118章第77章第76章第167章第51章第158章第95章第222章第83章第32章第194章第205章第158章第113章第59章第138章第223章第64章第192章第40章第142章第111章第168章第101章第37章第28章第15章第205章第171章第98章第177章第153章第88章第94章第103章第40章第30章第209章第34章第107章第192章第199章第14章第211章第206章第117章第167章第75章第140章第27章第214章第177章第89章第1章第148章第173章第139章第105章第226章第137章第165章第24章第126章第93章第220章第129章第55章第177章第173章第7章第105章第161章第209章第26章第73章第79章第162章第196章第196章第72章第41章第131章第181章第222章第199章
主站蜘蛛池模板: 桂林市| 乌兰察布市| 乌拉特后旗| 延川县| 江西省| 凌源市| 汝南县| 山东| 德安县| 林周县| 秦安县| 巴楚县| 九龙城区| 朝阳区| 阿克陶县| 景洪市| 通渭县| 陆河县| 鄂尔多斯市| 璧山县| 大厂| 女性| 上思县| 桐庐县| 朝阳区| 婺源县| 柯坪县| 锦州市| 岑巩县| 乐清市| 海口市| 保定市| 襄樊市| 阳原县| 怀宁县| 万州区| 连云港市| 桓台县| 邛崃市| 静乐县| 邹城市|