当前位置:   article > 正文

设计模式-02 设计模式-接口隔离原则案例分析

设计模式-02 设计模式-接口隔离原则案例分析
1.定义

接口隔离原则(Interface Segregation Principle,简称 ISP)是设计模式中的一个原则,它规定客户端不应该依赖它不使用的方法。

换句话说,接口应该被细分为更小的、更具体的接口,以便客户端只依赖于它们需要的方法。

  1. (客户端)
  2. |
  3. V
  4. (公共行为) (特定行为) (特定行为)
  5. +------------+ +-------------+ +-------------+
  6. | I公共接口 | | I特定接口1 | | I特定接口2 |
  7. +------------+ +-------------+ +-------------+
  8. | | |
  9. V V V
  10. +-------+ +---------+ +---------+
  11. | 客户端1 | | 客户端2 | | 客户端3 |
  12. +-------+ +---------+ +---------+

2.内涵


接口应该被细分的足够少,接口与接口直接不应该有依赖,ISP 的目的是提高代码的灵活性、可维护性和可测试性。总结起来,ISP原则的好处和缺点如下。
ISP 的好处

  •     提高代码的灵活性
  •     提高代码的可维护性
  •     提高代码的可测试性
  •     减少耦合
  •     提高代码的可重用性

ISP 的缺点

  •     可能导致更多的接口
  •     可能增加代码的复杂性
3.案例对比

例如,以机器类的定义为例,假如一个机器可以打印机,复印机,发传真机,如果不加以深入思考,我们可能如下第一种方式定义。


bad 设计

  1. //
  2. // Created by Administrator on 2024/5/1.
  3. //
  4. #include <iostream>
  5. using namespace std;
  6. struct Document;
  7. struct IMachine{
  8.     virtual void print(Document& doc) = 0;
  9.     virtual void scan(Document& doc) = 0;
  10.     virtual void fax(Document& doc) = 0;
  11. };
  12. // 接口分离原则
  13. // 发现 MFP  只需要 print 功能即可
  14. // 其他接口到底怎么处理比较好?
  15. struct MFP:IMachine{
  16.     void print(Document &doc) override {
  17.         // ok
  18.     }
  19.     void scan(Document &doc) override {
  20.     }
  21.     void fax(Document &doc) override {
  22.     }
  23. };
  24. // 发现scanner 只需要 scan 功能
  25. // 其他接口到底怎么处理比较好?
  26. struct Scanner:IMachine{
  27.     void print(Document &doc) override {
  28.         // do what?
  29.     }
  30.     void scan(Document &doc) override {
  31.         // ok
  32.     }
  33.     void fax(Document &doc) override {
  34.         // do what?
  35.     }
  36. };

如果后面的传真机怎么定义?,除了fax 函数外,其他函数的功能并不是fax 需要的。

好的设计

  1. #include <iostream>
  2. using namespace std;
  3. struct Document;
  4. // 接口分离
  5. struct IPrinter{
  6.     virtual void print(Document& doc) =0 ;
  7. };
  8. struct IScanner {
  9.     virtual void scan(Document& doc)=0 ;
  10. };
  11. struct IFax{
  12.     virtual void fax(Document& doc)=0 ;
  13. };
  14. struct IMachine:IPrinter,IScanner {
  15. };
  16. struct Machine:IMachine{
  17.     IPrinter& printer;
  18.     IScanner& scanner;
  19.     Machine(IPrinter &printer, IScanner &scanner):printer(printer),scanner(scanner){
  20.     }
  21.     void print(Document &doc) override {
  22.         printer.print(doc);
  23.     }
  24.     void scan(Document &doc) override {
  25.         scanner.scan(doc);
  26.     }
  27. };

这种设计,我们可以任意进行组合,组合出不同特性的子类,自由度更高。

4.注意事项


在实际开发中应用接口隔离原则(ISP)时,需要注意以下几点:

  • 识别公共行为。第一步是识别客户端共享的公共行为。这些行为可以被抽象到一个公共接口中。
  • 细化接口。对于任何不属于公共行为的方法,都应该将其细化到一个单独的接口中。
  • 考虑可扩展性。在设计接口时,考虑未来的可扩展性。避免将不相关的功能包含在同一个接口中。
  • 使用依赖注入。依赖注入是一种技术,它允许客户端只依赖于它们需要的接口。这有助于实现松耦合和可测试性。
  • 避免使用继承。继承是一种实现代码重用的强大机制,但它也可能导致违反 ISP。如果可能的话,优先使用组合而不是继承。

5.最佳实践


注意的具体示例:

  • 避免创建上帝接口。上帝接口是一个包含大量方法的大型接口。客户端通常只使用其中一小部分方法,但仍然必须实现所有方法。这违反了 ISP,并可能导致不必要的代码和维护开销。
  • 避免使用可选方法。可选方法允许客户端选择性地实现接口中的某些方法。这可能导致代码混乱和不可预测的行为。如果可能的话,避免使用可选方法,而是创建单独的接口来表示可选的行为。
  • 考虑未来需求。在设计接口时,考虑未来的需求。避免将不相关的功能包含在同一个接口中,因为这可能会限制接口的未来可扩展性。

6.总结


应用 ISP 时,权衡其优点和缺点非常重要。ISP 可以提高代码的灵活性、可维护性和可测试性,但它也可能导致更多的接口和增加代码的复杂性。

总体而言,ISP 是一个有用的设计原则,它可以帮助提高代码的质量。通过遵循上述准则,开发人员可以有效地应用 ISP,从而获得其好处,同时避免其潜在的缺点。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/543333
推荐阅读
相关标签
  

闽ICP备14008679号