企鹅的故事

来源:互联网 发布:java就业培训学费 编辑:程序博客网 时间:2024/06/11 12:06

本故事的主人公是企鹅小黑,他是一只鸟.

他继承了鸟可以飞的属性,但是小黑并不会飞.所以在这里企鹅是不能继承鸟的.

 

如果我们这样继承了就违反了软件设计的原则:

里氏替换原则:子类必需能够替换掉它的父类型.也就是子类指针可以赋给父类

也就是要保证父类具有的属性子类也必需有.

只有满足这一点才能够完美的继承复用.

 

可不可以把鸟会飞的这个属性去掉呢?这样的话就违反了另外一个原则:

开闭原则:对扩展开放对修改关闭.

 

也可能会想到,给小黑增加一个属性:.把父类中的飞覆盖掉不会任何事不就行了吗?会飞的鸟就不实现飞的属性,不会飞的就增加一个不做事.但这样也不是很好吧,对每一个鸟类都要去考虑,要不要这个属性多累啊.

 

但是现在假设我们就这么做:

小黑 = 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”;

         }

};

所以企鹅就飞不起来了.完美解决了这个问题.

 

 

策略模式要和简单工厂模式时行对比,可以找到策略模式的缺点,还有他们的共同点..

 

 

原创粉丝点击