pp看书笔记---设计模式之禅第二版 第二章【里氏替换原则】

来源:互联网 发布:sql 别名 编辑:程序博客网 时间:2024/05/04 23:22

定义

父类对象出现出现的地方可以用子类对象替换,且程序正常


作者阐释的4层含义

1.子类必须完全实现父类方法

2.子类可以有自己的个性

3.覆盖或实现父类的方法时传入的参数可以被放大

4.覆盖或实现父类的方法时输出结果可以被缩小


我对作者4层含义的解析

1.这里强制实现父类所有的方法是必须的,可以说语法所限,我们是面向接口编程,这个父类就是一个接口,一个抽象类,里面定义的方法能不完全实现吗?

2.子类可以有自己的个性,所谓个性,子类在实现的细节可以有自己的个性,因为他的框架已经定义好了抽象

3.这一条是对第一条的一个具体表现阐释,为什么这样说呢,我看懂书中给出重载基类方法的示例后写出这段继承基类接口的方法代码,是一样的

    class A{}    class B:A{}    interface IPerson    {        void Run(A num);    }    class Stu : IPerson    {        public void Run(A num)        {            Console.WriteLine("执行Stu");        }    }    static void Main(string[] args)    {       IPerson obj = new Stu();       obj.Run(new B());       Console.ReadKey();   }

obj是基类对象,实例化子类对象,传入的参数是B,比定义的方法参数A的范围大,当然你也可以传入A类型,大于或等于,这就是这一条的含义,Main中代码可以正常运行
将接口中Run方法的参数定义为B类型,那必然的Stu中Run方法的参数必须是B类型的,因为你是实现,那在Main中new B换成new A,是没法编译通过的
所以这样来看,这一条仅是里氏替换下的一跳允许的语法而已

4.这一条和第三条是一样的道理,可以自己写段代码即明白。


书中的示例

  1. CS游戏中,有一个基类:枪
  2. 士兵中只需拿到基类枪后可以杀敌
  3. 有手枪、AK、狙枪来实现枪
  4. 在士兵中枪对象不关心实例化的谁,但是都可以用枪的子类来实例化,来替换
  5. 如果有一天我需要加入B31,也很方便

我的记忆

我曾经看过篇博文,上面写道,玩家手持Wepon杀敌,用的是木剑、铁剑、倚天剑都可以很方便的加入


我学到的知识

  1. 可以总结成一条模板,遇到同类型情况,可以使用接口来写基类,同类型来继承基类实现,使用的地方使用基类对象,实例化不同子类即可,同类型情况例如:
    手枪、狙枪、冲锋枪
    木剑、铁剑、倚天剑
    云南白药牙膏、高露洁牙膏、黑人牙膏
    水笔、钢笔、油笔
    ……
    带来的好处:扩展方便(其他的优点和缺点没有感触或感触不深)

我的实践

我现在开发的程序S,有一个模块是工程管理,需要获取A公司提供的接口来获得,而我又知道S在B公司也有需求,我这里是这样设计的(很高兴的是我在这里也有用到单一职责):
这里写图片描述
我在S的主程序中实例化ProjectManager对象,在这个对象中IProjectSdk字段内部实例化为AcompanyProjectSdk,这个项目我即将开发完,如果有一天B公司也需要,这里就很好变化,在这里的AcompanyProjectSdk、BcomparyProjectSdk就是我眼里的木剑、铁剑


我的不足

在我刚刚绘制上面这个局部UML图时,我发现在依赖的时候,自己习惯的拖出<- - - - -,没有想的那么细的关系,是什么样的依赖,合成、组合、关联……

0 0