编程源自生活:抽象 -> 生活中的洗头问题
设计背景:
我:头上的油揩给了手,手接触洗手液。洗手液伤头皮,这样头皮就不会和洗手液接触了。
具体执行过程描述: 1.手揩油 -> 2.取液体 3.->洗手
我:这是什么设计模式?怎么实现?
===================================================================
广告兄<同城广告网>:
设计模式的核心就是面向抽象编程,你首先让手成为一个抽象的类,而不只是手,是一个可以把头上的油揩下来的抽象类,就可以了。
这样头只需要跟这个抽象类对象打交道就行了,而不用跟洗手液打交道了,洗手液也是面向这个可以揩油的抽象类打交道。
我:
的确需要一个抽象基手,我有时用左手揩油,有时右手,有时双手齐下。
广告兄:
除了上述设计一个可以揩油的抽象基手,另一种设计是将揩油动作实现为一个接口,接口中封装的是动作, 洗手液可以是揩油接口的具体实现,肥皂也可以是揩油接口的具体实现。
该接口的具体对象可以是:洗手液,肥皂,洗头液,洗发水等等。
我:
这个就是简单工厂模式,获取具体的液体,采用简单工厂模式。
简单工厂模式的使用,传入一个字符串来标识使用哪种液体即可。就可以获取到对应的具体的液体对象。
然后再调用洗手方法。ps:注意,然后是洗手: 1.手揩油 -> 2.取液体 3.->洗手
那手揩头皮油这块,怎么实现?
广告兄:
你不是抽象的手吗,
我:
手,可能也会揩身上的油,甚至是桌子上的污渍。手还能打人耳光!手是多功能的类对象。
广告兄:
没错啊 , 那就让手实现这个接口。 把揩油动作封装成一个抽象类,让手实现这个揩油动作的接口。
根据设计背景增加细节思考1:
我:
A 取洗手液的时候,同一时刻,只能允许一个对象(一只手)来取。因为洗手液的瓶子只有一个出口。(如果有两只手来取洗手液,取洗手液时就需要排队)
我:
B 取液体,可以由手来取。也可以用嘴巴来吸!谁来取液体,这个也是个问题。我们需要的是一条通用的取液体的通道,提供这条通道就可以了,而不必关心谁来取。
广告兄:
实现取液体这个接口就可以了,或者说实现取液体这个抽象类。
我:
该抽象类内部维护一个取液体的纯虚函数。
广告兄:
C++中不太推荐,因为这样就是多重继承了,也就是说手是揩油动作这个抽象类的子类,也是取液体这个抽象类的子类。
手可以是任何类的子类,手甚至可以飞,只要实现飞的接口就可以了。手也可以游泳,实现游泳的接口就可以了。
我:
是的,手还能打人,擦屁股,放鞭炮,手的天生属性就是多功能。手,面临随时可能被拓展功能需求。
广告兄:
用C++的语言来说,就是实现相应的抽象类。
我:
你这个设计挺巧妙的,中文字面意思,我说的是手能打人,能洗手,能放鞭炮。
而你的实现相当于变成了: 会打人的有:手 。 会放鞭炮的有: 手 。
因为你的实现是让手成为打人这个抽象类的子类。
广告兄:
go中的接口全是这样的,不叫纯虚抽象类了,就叫接口,interface。
我:
小结,1.在手这个类中需要实现揩油和取液体,这俩虚函数定义。可以使用打印语句:"现在是手揩油",“现在是手在取液体” 作为函数体内容代替。
2,取液体,是个全局函数,内部使用简单工厂模式实现。
3,揩油,准确地说是揩头皮油,揩油也有很多细分场景,例如揩桌布油,揩机油,而我们当前需求是揩头皮油。
根据当前的聊天思路,揩头皮油揩桌布油,揩机油分别设计为不同的抽象类。
增加细节思考2 -- 升华模板技术!
我:
揩油,和取液体,语义上如此类似: 一个动词,后面跟一个名词!
那是不是可以使用模板技术,进一步提取和统一化呢?!
我想肯定可以! 有待日后提升!
这个函数模板的设计可能也有难点吧,这里头还使用了简单工厂模式。
可以称之为: 带简单工厂模式设计的函数模板。
.