可靠的设计原则:软件,即易于维护、重用和扩展

2020-05-26 14:33:51

C++中的接口隔离原则是迄今为止最简单的系列固体As a Rock设计原则中的第四个原则。坚实的设计原则着眼于开发易于维护、可重用和可扩展的软件。在这篇文章中,我们将看到一个违反ISP的代码,一个解决ISP相同代码、准则和利益的解决方案。

顺便说一下,如果您还没有读过我以前关于设计原则的文章,那么下面是快速链接:

您在本系列文章中看到的代码片段是简化的,而不是复杂的。所以你经常看到我不使用诸如Override、Final、Public(虽然继承)这样的关键字,只是为了使代码紧凑和可使用(在大多数情况下)在单一的标准屏幕大小中。我也更喜欢struct而不是class,因为有时不编写“public:”来节省行,而且还故意遗漏了虚拟析构函数、构造函数、复制构造函数、前缀std::、删除动态内存。我也认为自己是一个务实的人,希望以尽可能简单的方式传达一个想法,而不是用标准的方式或使用行话。

如果您是直接在这里跌跌撞撞的,那么我建议您检查一下什么是设计模式?首先,即使它是微不足道的。我相信它会鼓励你在这个话题上进行更多的探索。

您在本系列文章中遇到的所有代码都是使用C++20编译的(尽管我在大多数情况下使用的是最高可达C++17的现代C++特性)。因此,如果您无法访问最新的编译器,您可以使用https://wandbox.org/,它也预装了Boost库。

接口分离原则与单一责任原则密切相关。它真正的意思是,您应该始终以这样一种方式设计您的抽象,即使用公开方法的客户端不必得到整个馅饼。这会让客户端承担实现他们实际上并不需要的方法的负担。

struct document;struct imachine{虚拟无效打印(document&;doc)=0;虚拟无效传真(document&;doc)=0;虚拟无效扫描(document&;doc)=0;};struct多功能打印机:imachine{//确定无效打印(document&;doc)覆盖{}void fax(document&;doc)覆盖{}void扫描(文档&;doc)覆盖{}};struct扫描仪:imachine{//不确定无效打印。文档)覆盖{/*空白*/}无效传真(文档和amp;doc)覆盖{/*空白*/}无效扫描(文档和amp;doc)覆盖{//进行扫描.}};

正如您所看到的,就MultiFunctionPrinter而言,实现由imachine接口强制执行的print()、fax()和amp;scan()方法是可以的。

但是,如果您只需要一个扫描仪或打印机,某些开发人员仍然继承了机器&;将不必要的方法留空或抛出NotImplemented异常,无论哪种方式,您都做错了。

/*-*/struct IPrinter{virtual void print(document&;doc)=0;};struct iScanner{virtual void scan(document&;doc)=0;};/*--*/struct Printer:IPrinter{void print(document&;doc)Override;};struct Scanner:iScanner{void Scan(document&;doc)Override;};struct imachine:IPrinter,iScanner{};struct Machine:imachine{IPrinter&;m_Printer;iScanner&;m_scanner;Machine(IPrinter&;p,iScanner&;s):打印机{p},scanner{s}{}void print(document&;doc)override{printer.print(Doc);}void scan(document&;doc)override{scanner.scan(Doc);}};

这为客户端提供了灵活性,可以按照他们认为合适的方式组合抽象,并在没有不必要负担的情况下提供实现。

正如单一责任原则中所解释的那样。您应该避免具有多个职责的类&;接口。因为它们经常更改,使您的软件很难维护。您应该尝试根据角色将接口拆分成多个接口。

如果您违反了ISP,即将方法一起填充到接口中,并且当方法签名更改时,您需要重新编译所有派生类。这是一些编译语言(如C++)的一个重要方面,C++以编译速度慢而闻名。而另一种方式则是不言而喻的。

Martin还提到,“胖接口”-带有额外无用方法的接口-会导致类之间的无意耦合。因此,经验丰富的开发人员知道耦合是可重用性的祸害。

ISP更普遍的好处是,通过避免不必要的依赖,系统变得。

同样,对于代码的读者来说,从类声明行很难了解类的作用。因此,如果dev只看到一个可能继承了其他接口的神接口,可能不会很明显。比较

当您通过确定域中的主要角色开始分解您的问题空间时,这个原则自然就会出现。因此,它从来不是机械作用。

尽管大接口是一个潜在的问题,但ISP并不关心接口的大小。相反,它是关于类是否使用它们所依赖的接口的方法。因此,ISP在设计软件时是一个糟糕的指导,但却是衡量它是否健康的一个很好的指标。

你喜欢吗,☝️?将此类文章直接放入收件箱…。📥