16

Liskov替换原则(LSP)和接口隔离原则(ISP)之间有什么核心区别吗?最终,两者都保证设计具有通用功能的界面,并在您有特殊用途的功能时引入新界面。

4

3 回答 3

21

LSP:子类型必须遵守它所承诺的契约。

ISP:调用者不应该依赖于比它需要的更多的基类型接口。

它们适合的地方:如果应用 ISP,则只使用接收器完整接口的一部分。但根据 LSP,接收方仍必须遵守该切片。

如果你没有申请 ISP,就会有违反 LSP 的诱惑。因为“这个方法无所谓,实际上不会被调用”。

于 2019-02-03T05:33:28.097 回答
9

两者都是SOLID原则

  • LSP(Liskov Substitution):此原则要求您确保所有子类与父类具有相同的行为。例如:如果您有一个Device类并且它具有callBaba()获取您父亲电话号码然后给他打电话的功能,那么您必须确保callBaba()所有子类中的方法都Device执行相同的工作。如果其中的任何子类 Device有其他行为,callBaba()则意味着您破坏了 LSP

违反 Liskov 原则的代码示例。

class Device {
    func callBaba() {
        print("I will find your father and I will call him")
    }
}

class Calculator: Device {
    override func callBaba() {
      print("Sorry, I don't have this functionality ")
    }
}

解决方案

interface CanCall {
            func callBaba()
        }
        class Device {
            // all basic shared functions here.
        }

        class Calculator: Device {
            // all functions that calculator can do + Device
        }
        class SmartPhone: Device implements CanCall {
            // all smartphone stuff
            func callBaba() {
                print("I will find your father and I will call him")
            }
        }
  • ISP(Interface Segregation):要求您为不同的职责创建不同的接口,换句话说,不要将不相关的行为分组在一个接口中,如果您已经有一个具有许多职责的接口,那么您就破坏了 ISP,而实现者没有需要所有这些东西

这违反了 ISP 原则,因为它有两个不同的职责

  protocol Animal {
        func fly()
        func eat()
    }

解决方案

protocol Flyable {
    func fly()
}
protocol Feedable {
    func eat()
}
于 2019-07-20T16:52:05.287 回答
8

LSP 管理父类和子类之间的关系(即层次关系)。它告诉您如何实现 API。

ISP 管理父类和客户类之间的关系(即生产者/消费者关系)。它告诉您何时实现 API。

考虑一个包含一百个方法的接口。一个子类可以在不违反其中任何一个定义的契约的情况下实现所有一百个,从而满足 Liskov Substitution;但是很难想象每个客户端都需要所有这些方法,因此几乎肯定会违反接口隔离。

相反,只有一种方法的接口肯定满足接口隔离;但是如果一个实现不遵守那个方法契约,那么就违反了 Liskov Substitution。

另请参阅:LSP 与 DIP

于 2020-12-29T23:02:10.923 回答