面向对象的五大设计原则之里氏替换原则

里氏替换原则(liskov substitution principle,简称LSP)的核心只有一句话,subtypes must be substitutable for their base types(子类必须能够替换成它们的基类),关于它的定义和主要的思想如下:

由于面向对象编程技术中的继承再具体的编程过程中过于简单,在许多系统的设计和编程实现中,我们并没有认真的、理性的思考应用系统中各个类之间的继承关系是否合适,派生类是否能正确的对其它基类中的某些方法进行重写等问题,因此,经常出现滥用继承或者错误的进行了继承等现象,给系统后期的维护,带来了不少麻烦,这就需要我们设计一个原则来遵循,所以,里氏替换原则,应运而生。

里氏替换原则指出,子类型必须能够替换掉它们的父类型,并出现在父类能够出现的任何地方,这个原则指导我们如何正确的进行继承和派生,并且合理的重用代码,这个原则认为,一个软件实体,如果使用一个基类的话,那么一定适用于其子类,而且根本察觉不出来基类对象和子类对象之间的区别,感觉跟多态有点类似。

因为继承和派生是面向对象(OOP)的一个主要特征,而里氏替换原则则能够解决减少代码的重复编程实现、实现系统的代码复用、正确合理的使用和设计继承,来看下具体的方式。

首先,父类方法都要在子类中实现或者重写,并且派生类只是实现其抽象类中声明的方法,而不应当给出多余的方法定义或者实现,其次,在客户端程序中,只应该使用父类对象,而不能直接使用子类对象,这样可以实现运行期的绑定(动态绑定),最后呢,如果A、B两个类违反了里氏替换原则,通常的做法就是创建一个新的抽象类C,作为两个类的超类,将A和B的共同行为,移植到C中,从而解决A和B行为不完全一致的问题。

其实,PHP对于里氏替换原则的支持并不好,它本身缺乏向上转型啊什么的概念,我们来看一个关于缓存实现抽象类的代码感受下,抽象代码应该咋写,没有具体的实现类啊:

/*设置缓存实现抽象类*/
abstract class cache
{
    /*设置缓存变量,$k键值,$v缓存值,$time缓存过期时间*/
    public abstract function set($k,$v,$time=60);
    /*获取已经缓存的一个变量*/
    public abstract function get($k);
    /*删除一个已经缓存的变量*/
    public abstract function del($k);
    /*删除全部缓存变量*/
    public abstract function del_all();
    /*检测是否存在相对应的缓存*/
    public abstract function has($k);
}

我们如果要用作什么memcache等各种机制下的缓存,只需要继承这个抽象类并且实现抽象类中的方法就好了。

我们要注意的是,里氏替换原则中替换的不仅仅是功能,还包括语意。

好啦,本次记录就到这里了。

如果感觉不错的话,请多多点赞支持哦。

你可能感兴趣的:(原创)