穿什么有这么重要?大佬展开说了说装饰模式

1 穿什么有这么重要?

时间:3月16日20点  地点:大鸟房间  人物:小菜、大鸟

"大鸟,明天我要去见娇娇了,你说我穿什么去比较好?"小菜问大鸟道。

"这个你也来问我,干脆我代你去得了。"大鸟笑言。"别开玩笑,我是诚心问你的。"

"哈哈,小菜呀,你别告诉我说四年大学你都没和女生约过会?"

"唉!谁叫我念的是理工科大学呢,学校里本来女生就少,所以这些稀有宝贝们,大一时早就被那些老手们主动出击搞定了,我们这些恋爱方面的小菜哪还有什么机会,一不小心就虚度了四年。"小菜突生伤感,叹气摇头,并小声地唱了起来,"不是我不小心,只是真情难以寻觅,不是我存心故意,只因无法找到良机……"

"喂!"大鸟打断了小菜,"差不多行了,感慨得没完没了。说正事,问我什么?"

"哦,你说我穿什么去见娇娇比较好?"

"那要看你想给人家什么印象?是比较年轻,还是比较干练;是比较颓废,还是要比较阳光;也有可能你想给人家一种极其难忘的印象,那穿法又大不一样了!"

"你这话怎么讲?"

"年轻,不妨走点Hip-Hop路线,大T恤、垮裤、球鞋,典型的年轻人装扮。"

"啊,这不是我喜欢的风格,我从来也没这样穿过。"

"那就换一种,所谓干练,就是要有外企高级白领的样,黑西装、黑领带、黑墨镜、黑皮鞋……"

"你这叫白领?我看是社会人。不行不行。"

"哈,来颓废的吧,颓废其实也是一种个性,可以吸引一些喜欢叛逆的女生。一般来说,其标志是:头发可养鸟、胡子能生虫、衬衣没纽扣、香烟加狐臭。"

"这根本就是'肮脏'的代表吗,开什么玩笑。你刚才提到给人家难忘印象,是什么样的穿法?"

"哈,这当然是绝妙的招了,如果你照我说的去做,娇娇想忘都难。"

"快说快说,是什么?"

"大红色披风下一身蓝色紧身衣,胸前一个大大的'S',表明你其实穿的是'小号',还有最重要的是,一定要'内裤外穿'……"

" 喂 , 你 拿 我 寻 开 心 呀 , 那 是 ' 超 人 ' 的 打 扮 呀 , 'S' 代 表 的 也 不是'Small',是'Super'的意思。"小菜再次打断了大鸟,还是忍不住笑道,"我如果真的穿这样的服装去见MM,那可真是现场的人都终生难忘,而小菜我,社死现场,这辈子也不要见人了。"

"哈,你终于明白了!我其实想表达的意思就是,你完全可以随便一些,平时穿什么,明天还是穿什么,男生嘛,只要干净一些就可以了,关键不在于你穿什么,而在于你人怎么样。对自己都这么没信心,如何追求女孩子?"

"哦,我可能是多虑了一些。"小菜点头道,"好吧,穿什么我自己再想想。没什么事了吧?那我回房了。"

"等等,"大鸟叫住了他,"今天的模式还没有开讲呢,怎么就跑了?"

"哦,我想着约会的事,把学习给忘了,今天学什么模式?"

2 小菜扮靓第一版

结构图

"先不谈模式,说说你刚才提到的穿衣问题。我现在要求你写一个可以给人搭配不同服饰的系统,比如类似QQ、电商平台或游戏都有的Avatar系统。你怎么开发?"

"你是说那种可以换各种各样的衣服裤子的个人形象系统?"

"是的,现在你就简单点,用控制台的程序,写可以给人搭配嘻哈服或白领装的代码。"

"哦,我试试看吧。"

半小时后,小菜的第一版代码出炉。Person类:

客户端代码:

结果显示:

"哈,不错,功能是实现了。现在的问题就是如果我需要增加'超人'的装扮,你得如何做?"

"那就改改Person类就行了,"小菜说完就反应过来,"哦,不对,这就违背了开放-封闭原则了。哈,我知道了,应该把这些服饰都写成子类就好了。我去改。"

大鸟抬起手伸出食指对小菜点了点,"你呀,刚学的这么重要的原则,怎么还会忘?"

3 小菜扮靓第二版

过了不到十分钟,小菜的第二版代码出炉。

Person类:

服饰抽象类:

各种服饰子类:

注意上面都是继承Finery类,其余类类似,省略。

客户端代码:

结果显示同前例,略。

"这下你还能说我不面向对象吗?如果要加超人装扮,只要增加子类就可以了。"

"哼,用了继承,用了抽象类就算是用好了面向对象了吗?你现在的代码的确做到了'服饰'类与'人'类的分离,但其他问题还是存在的。"

"什么问题呢?"

"你仔细看看这段代码。"

"这样写意味着什么?"大鸟问道。

"就是把'大T恤''垮裤''破球鞋'和'装扮的小菜'一个词一个词地显示出来呀。"

"说得好,我要的就是你这句话,这样写就好比:你光着身子,当着大家的面,先穿T恤,再穿裤子,再穿鞋,仿佛在跳穿衣舞。难道你穿衣服都是在众目睽睽下穿的吗?"

"你的意思是,应该在内部组装完毕,然后再显示出来?这好像是建造者模式呀。"

"不是的,建造者模式要求建造的过程必须是稳定的,而现在我们这个例子,建造过程是不稳定的,比如完全可以内穿西装,外套T恤,再加披风,打上领带,皮鞋外再穿上破球鞋;当然也完全可以只穿条裤衩就算完成。换句话就是说,通过服饰组合出一个有个性的人完全可以有无数种方案,并非固定的。"

"啊,你说得对,其实先后顺序也是有讲究的,如你所说,先穿内裤后穿外裤,这叫凡人,内裤穿到外裤外面,那就是超人了。"

"哈,很会举一反三嘛,那你说该如何办呢?"

"我们需要把所需的功能按正确的顺序串联起来进行控制,这好像很难办哦。"

"不懂就学,其实也没什么稀罕的,这可以用一个非常有意思的设计模式来实现。"

4 装饰模式

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。[DP

"啊,装饰这词真好,无论衣服、鞋子、领带、披风其实都可以理解为对人的装饰。"

"我们来看看它的结构。"

装饰模式(Decorator)结构图

"Component是定义一个对象接口,可以给这些对象动态地添加职责。

ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职 责 。 Decorator , 装 饰 抽 象 类 , 继 承 了 Component , 从 外 类 来 扩 展Component类的功能,但对于Component来说,是无须知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能[DPE]。"

"来看看基本的代码实现。"

"我明白了,原来装饰模式是利用SetComponent来对对象进行包装的。

这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中[DPE]。用刚才的例子来说就是,我们完全可以先穿外裤,再穿内裤,而不一定要先内后外。"

"既然你明白了,还不快些把刚才的例子改成装饰模式的代码?"大鸟提醒道。

" 还 有 个 问 题 , 刚 才 写 的 那 个 例 子 中 ' 人 ' 类 是 Component 还 是ConcreteComponent呢?"

"哈,学习模式要善于变通,如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把DecoratorConcreteDecorator的责任合并成一个类。"

"啊,原来如此。在这里我们就没有必要有Component类了,直接让服饰类Decorator继承人类ConcreteComponent即可。"

5 小菜扮靓第三版

二十分钟后,小菜第三版代码出炉。

代码结构图

ICharacter接口(Component):

Person类(ConcreteComponent):

Finery类(Decorator):

具体服饰类(ConcreteDecorator):

其余类类似,省略。

客户端代码:

结果显示:

"如果我换一种装饰方式,比如说,增加草帽装扮,再重新组合一下服饰,应该如何做?"大鸟问道。

"那就增加一个草帽子类,再修改一下装饰方案就好了。"小菜开始写代码。

结果显示:

"哈,戴着草帽、光着膀子、打着领带、下身垮裤、左脚皮鞋、右脚球鞋的极具个性的小菜就展现在我们面前了。"

"你这家伙,又开始拿我开涮。我要这样,比扮超人还要丢人。"小菜抱怨道,"我在想,上一次说的策略模式,使用了商场收银软件,是否存在使用装饰模式的情况?"

"好问题。事实上是有机会用的。比如说,我们商场10周年庆,要加大力度回馈客户,所有商品,在总价打8折的基础上,再满300返100,当然这只是一种销售方案,还可以是打7折,再满200送50,或者满300返50,再打7折,也就是说,可以多种促销方案组合起来使用。我们的要求是最终实现的代码,影响面越小越好,也就是原来的代码能利用就要利用,改动尽量小一些。你可以考虑一下如何做。"

6 商场收银程序再升级

小菜:"我想想。我完全可以写个复杂的算法,先打8折,再满300返100,算法可以是下面这样。"

增加一个先折扣再返利的算法子类,初始化需要三个参数,并在计算时,先打折,再返利计算。

修改CashContext类,增加一个先打8折再满300返100的算法实例对象。

大鸟:"你这确实是达到了增加一种组合算法的功能实现,但你有没有发现,新类CashReturnRebate有原来的两个类:CashReturnCashRebate有大量重复的代码?"

小菜:"是呀,我等于是把两个代码合并又写了一遍。"

大鸟:"另外,如果我现在希望增加一个先满300返100,再打折扣的算法,你如何修改呢?再写一个新类吗?如果我们再增加购买送积分、购买抽奖、购买送小礼品等算法,并且有了各种各样的先后组合,你打算怎么处理呢?"

小菜:"我……这个……"

大鸟:"哈哈,好好想想吧。装饰模式或许能帮到你。"

小菜:"我懂你意思了。看来我前面没有真的理解装饰模式。我再来试试。"

7 简单工厂+策略+装饰模式实现

小 菜 : " 无 须 增 加 CashReturnRebate 类 , 依 然 是 CashNormalCashReturnCashRebate三种基本算法子类。增加一个接口ISale,用作装饰模式里的Component。"

大鸟:"你这样是可以实现同样的功能,但与装饰模式比较起来,并不完美。仔细对比观察一下,还有什么东西没有?"

小菜:"哦!我发现了,ConcreteComponent类不存在。那它应该是什么呢?"

大鸟:"装饰模式有一个重要的优点,把类中的装饰功能从类中搬移去除,这样可以简化原有的类。我们现在的三个算法类,有没有最基础的呢?"

小 菜 : "CashNormal 是 最 基 础 的 。 哦 ! 我 知 道 了 , 是 把 它 作 为ConcreteComponent。我马上重构一下。"

CashSuper原来是抽象类,改成普通类,但实现ISale接口。

CashNormal,相当于ConcreteComponent,是最基本的功能实现,也就是单价 数量的原价算法。

另 外 两 个 CashSuper 的 子 类 算 法 , 都 在 计 算 后 , 再 增 加 一 个super.acceptCashresult, 1)返回。

重点在CashContext类,因为涉及组合算法,所以用装饰模式的方式进行包装,这里需要注意包装的顺序,先打折后满多少返多少,与先满多少返多少,再打折会得到完全不同的结果。

客户端算法不变:

结果显示:

单位1000元,数量为1的商品,原需支付1000元,如果选择先8折再满300送100算法的话,就是1000 0.8=800元,满足两个300元,返200元,最终结果是客户只需支付600元。

单位500元,数量为4的商品,原需支付2000元,如果选择先满200送50再7折算法的话,就是2000中有10个200,送10 50=500元,所以2000-500=1500元,再打7折,1500 0.7,最终结果是客户只需支付1050元。

大鸟:"非常棒!你完全实现了三个模式结合后的代码。现在的代码比刚才的想法好在哪里?"

小菜:"嗯!我也觉得很兴奋。现在无论如何组合算法,哪怕是先打折再返现,再打折再返现,我都只需要更改CashContext类就可以了。目前代码确实做到了开放封闭。设计模式真是好!"

8 装饰模式总结

"来来来,总结一下,你感觉装饰模式如何?""我觉得装饰模式是为已有功能动态地添加更多功能的一种方式。但到底什么时候用它呢?"

"答得很好,问的问题更加好。你起初的设计中,当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,比如用西装或嘻哈服来装饰小菜,但这种做法的问题在于,它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,就像你起初的那个'人'类,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。

而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了[DP]。所以就出现了上面那个例子的情况,我可以通过装饰,让你全副武装到牙齿,也可以让你只挂一丝到内裤。"

"就像你所说的,装饰模式的优点是,把类中的装饰功能从类中搬移去除,这样可以简化原有的类。像前面的原价算法就是最基础的类,而打折或返现,都算是装饰算法了。"

"是的,这样做更大的好处就是有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。我们不必去重复编写类似打折后再返现,或返现后再打折的代码,对于装饰模式来说,只是多几种组合而已。"

"这个模式真不错,我以后要记着常使用它。"

"你可要当心哦,装饰模式的装饰顺序很重要哦,比如加密数据和过滤词汇都可以是数据持久化前的装饰功能,但若先加密了数据再用过滤功能就会出问题了,最理想的情况,是保证装饰类之间彼此独立,这样它们就可以以任意的顺序进行组合了。"

"是呀,穿上西装再套上T恤实在不是什么好穿法。"

"明天想好了要穿什么去见MM了吗?"大鸟突然问道。

"有了装饰模式,我还用得着担心我的穿着?再说,我信奉的是《天下无贼》中刘德华说的一句经典台词:'开好车就是好人吗?',小菜我魅力无限,不需装饰。"

大鸟惊奇地望着小菜,无法理解地说了句:"学完模式,判若两人,你够弓虽!"

展开阅读全文

页面更新:2024-03-19

标签:大佬   模式   组合   子类   小菜   算法   顺序   对象   代码   功能   服饰

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top