看我七十二变
有近2星期沒(méi)有寫(xiě)文章了,各種原因吧,主要是懶。
今天接著寫(xiě)吧,今天寫(xiě)一個(gè)孫悟空的七十二變。
變樹(shù)、變房、變小女孩
我們會(huì)用到裝飾模式,裝飾模式是結(jié)構(gòu)型設(shè)計(jì)模式的一種。
裝飾模式也可以叫包裝(Wrapper)模式,我對(duì)他的理解就是他替代了繼承操作。
比如我們寫(xiě)一個(gè)孫悟空七十二變的例子,用繼承是這么做的:
代碼很簡(jiǎn)單就不寫(xiě)了,類(lèi)圖是這樣子的
一、裝飾模式類(lèi)圖
- 抽象構(gòu)件(Component)角色:這是一個(gè)抽象接口,用以規(guī)范準(zhǔn)備附加責(zé)任的對(duì)象
- 具體構(gòu)件(ConcreteComponent)角色:這是一個(gè)具體的準(zhǔn)備接受附加責(zé)任的對(duì)象
- 裝飾(Decorator)角色:這是一個(gè)抽象修飾類(lèi),他持有一個(gè)Component對(duì)象
- 具體裝飾(ConcreteDecorator)角色:負(fù)責(zé)給持有對(duì)象Component附加責(zé)任
那具體到我們這個(gè)七十二變的例子中類(lèi)圖是什么樣的呢?
注意:不要太在意這里的繼承和實(shí)現(xiàn),我們開(kāi)發(fā)中可以用抽象類(lèi)子類(lèi)繼承,也可以用接口然后編寫(xiě)實(shí)現(xiàn)
二、讓我們變(編)起來(lái)
取經(jīng)人:
package decorate;/*** @author 木子的晝夜編程*/ public interface BibleReader {void change(); }豬八戒、孫悟空:
package decorate;/*** @author 木子的晝夜編程*/ public class SunWuKong implements BibleReader{@Overridepublic void change() {System.out.print("孫悟空");} } package decorate;/*** @author 木子的晝夜編程*/ public class ZhuBaJie implements BibleReader{@Overridepublic void change() {System.out.print("豬八戒");} }裝飾類(lèi):
package decorate;/*** @author 木子的晝夜編程*/ public abstract class Decorator implements BibleReader {BibleReader bb ;public Decorator(BibleReader bb) {this.bb = bb;}@Overridepublic void change(){if (bb != null) {bb.change();}} }裝飾變樹(shù):
package decorate;/*** @author 木子的晝夜編程*/ public class TreeDecorator extends Decorator{public TreeDecorator(BibleReader bb) {super(bb);}// 獨(dú)有的裝飾方式private void myDecorator(){System.out.println("--變樹(shù)!!");}@Overridepublic void change(){if (bb != null) {bb.change();}myDecorator();} }裝飾變房子:
package decorate;/*** @author 木子的晝夜編程*/ public class HouseDecorator extends Decorator{public HouseDecorator(BibleReader bb) {super(bb);}// 獨(dú)有的裝飾方式private void myDecorator(){System.out.println("--變房子!!");}@Overridepublic void change(){if (bb != null) {bb.change();}myDecorator();} }裝飾變小女孩:
package decorate;/*** @author 木子的晝夜編程*/ public class GirlDecorator extends Decorator{public GirlDecorator(BibleReader bb) {super(bb);}// 獨(dú)有的裝飾方式private void myDecorator(){System.out.println("--變小女孩!!");}@Overridepublic void change(){if (bb != null) {bb.change();}myDecorator();} }開(kāi)始變:
package decorate;/*** @author 木子的晝夜編程*/ public class TestChange {public static void main(String[] args) {// 孫悟空本空SunWuKong sunWuKong = new SunWuKong();// 豬八戒本豬ZhuBaJie zhuBaJie = new ZhuBaJie();// 孫悟空變小女孩裝飾類(lèi)GirlDecorator girlDecorator = new GirlDecorator(sunWuKong);girlDecorator.change();// 孫悟空變房子裝飾類(lèi)HouseDecorator houseDecorator = new HouseDecorator(sunWuKong);houseDecorator.change();// 豬八戒變小女孩GirlDecorator girlDecoratorZhuBajie = new GirlDecorator(zhuBaJie);girlDecoratorZhuBajie.change();// 豬八戒變樹(shù)TreeDecorator treeDecorator = new TreeDecorator(zhuBaJie);treeDecorator.change();} }三、還有誰(shuí)?
這時(shí)候如果沙悟凈也想變,那我們只需要定義一個(gè)BibleReader的子類(lèi),然后就可以給他裝飾各種變換
不用再針對(duì)每種變換再定義子類(lèi)。
這就是我開(kāi)頭說(shuō)的,我理解裝飾就是用聚合代替了繼承
看到這里是不是覺(jué)得它很像代理模式,橋接模式?
是的!
等你全部領(lǐng)悟了之后,可以達(dá)到心中無(wú)劍手中有劍,也就是你沒(méi)想著用某種設(shè)計(jì)模式,但是你寫(xiě)出來(lái)的代碼已經(jīng)符合了某種設(shè)計(jì)模式。
比如: 1+1=2
比如:有人伸手打你,你會(huì)出手阻擋
比如:時(shí)間到了10點(diǎn)50 ,你就拿手機(jī)定外賣(mài)
總結(jié)
- 上一篇: 问题1084:搭数字Ⅰ
- 下一篇: Css知识回顾