企鹅的故事
本故事的主人公是企鵝小黑,他是一只鳥.
他繼承了鳥可以飛的屬性,但是小黑并不會飛.所以在這里企鵝是不能繼承鳥的.
?
如果我們這樣繼承了就違反了軟件設計的原則:
里氏替換原則:子類必需能夠替換掉它的父類型.也就是子類指針可以賦給父類
也就是要保證父類具有的屬性子類也必需有.
只有滿足這一點才能夠完美的繼承復用.
?
可不可以把鳥會飛的這個屬性去掉呢?這樣的話就違反了另外一個原則:
開閉原則:對擴展開放對修改關閉.
?
也可能會想到,給小黑增加一個屬性:飛.把父類中的飛覆蓋掉不會任何事不就行了嗎?會飛的鳥就不實現飛的屬性,不會飛的就增加一個不做事.但這樣也不是很好吧,對每一個鳥類都要去考慮,要不要這個屬性多累啊.
?
但是現在假設我們就這么做:
鳥 小黑 = new 企鵝();
小黑.飛();
?
?
void 動物世界::運動(鳥 tmp)
{
???????? tmp.飛();
}
動物世界 aa;
aa.運動(new 企鵝());
?
這樣使用是不是很舒服啊,呵呵.只有子類型的可替換性才使得父類型的模塊在無需修改的情況下就可擴展.所以在設計的時候一定要符合里氏替換原則.
?
?
這里用到了另外一個原則:依賴倒轉原則.
前段時候我可能說的不是很明白.
?
依賴倒轉原則:
高層模塊都依賴于抽象不依賴于具體實現. 在這里動物世界這個類沒有直接去使用企鵝這個類.
?
上面我們雖然假設企鵝可以繼承父類的飛的屬性,但這是假設.現在應該怎么進行改進呢?那就把飛的這個屬性給去掉吧,看下面的實現方法.
?
?
在這里我們使用策略模式.
?
企鵝從父類繼承了Flayable *flyornot的成員變量. 我們在初始化企鵝的時候就給這個變量賦成FlyNoWay;
flayornot = new FlyNoWay();
這樣在調用 flayornot.fly(); 的時候由于FlyNoWay里面的fly函數是這樣的:
?
class FlyNoWay
{
public:
???????? void fly()
???????? {
?????????????????? cout << “cann’t fly”;
???????? }
};
所以企鵝就飛不起來了.完美解決了這個問題.
?
?
策略模式要和簡單工廠模式時行對比,可以找到策略模式的缺點,還有他們的共同點..
?
?
總結
- 上一篇: 《缠中说禅108课》79:分型的辅助操作
- 下一篇: PLM-物料导入