isp设计模式(设计原则之接口分离原则)

单一职责原则倾向于设计视角,接口分离原则倾向于实现视角,二者看起来非常相似,但是在某些方面还是有所区别的,下面我们就来说一说关于isp设计模式?我们一起去了解并探讨一下这个问题吧!

isp设计模式(设计原则之接口分离原则)

isp设计模式

简介

单一职责原则倾向于设计视角,接口分离原则倾向于实现视角,二者看起来非常相似,但是在某些方面还是有所区别的。

定义

接口分离原则(Interface Segregation Principle):使用方不应该依赖于它不使用的方法(no client should be forced to depend on methods it does not use.)。

ISP 原则是用来处理胖接口或胖基类的,接口或类中包含了茫茫多的方法就称为胖接口或胖基类(简称小胖吧)。使用方在使用小胖的时候,会发现自己没有必要实现某个方法,但由于在小胖中存在,自己不得不实现一个,要么是空方法,要么抛出异常以表明自己不支持。

这时候就需要 ISP 原则出场了,它指导你将接口划分成更小的粒度,使用方只需要实现自己需要的接口即可,而不用继承小胖导致不得不实现小胖交代下来的任务。

实践

在设计原则只里氏替换原则中,我们举的例子就违反了接口分离原则,这里再举一个例子说明这个原则。

需求要求我们做一个二手书设计,要求我们记录书的基本信息,收购的基本信息,以及二手书的鉴定信息等信息。

设计的接口如下:

public interface Book { public String isbn(); public String author(); public Date publishDate(); public PublisherInfo publisher(); public PurchaseInfo purchaseInfo(); public IdentificationInfo identificationInfo(); }

接口工作良好,很好的支持了网站的运行。但由于业务的变化,网站现在不仅仅要卖二手书了,还要卖新书。这时只是缺少了收购信息和鉴定信息,但是新书本质上还是书,因此我们直接实现了 Book 接口来卖新书。

public abstract class NewBook implements Book { public PurchaseInfo purchaseInfo() { return null; } public IdentificationInfo identificationInfo() { return null; } }

所有的新书都使用 NewBook 接口,改动也很小就支持了新书的销售,很美好。

这个设计就违反了 ISP 原则,Book 强制所有的书都必须有收购信息和鉴定信息,但新书却并没有这两项,将新书实现 Book 接口强制新书也必须要有这两项信息,无奈只能使用折中办法返回null。

要改变这种情况,我们需要将收购信息和鉴定信息单独拆到一个接口中,二手书的实现继承这个接口,而新书的实现不继承这两个接口。

public interface Book { public String isbn(); public String author(); public Date publishDate(); public PublisherInfo publisher(); public PurchaseInfo purchaseInfo(); public IdentificationInfo identificationInfo(); } public interface SecondHand { public PurchaseInfo purchaseInfo(); public IdentificationInfo identificationInfo(); }

接口拆分成这样已经满足网站的要求了,如果后面网站发展越来越大,鉴定成本不可承受时,有些书籍不作鉴定直接入库,这时我们就需要将 SecondHand 接口再拆分成两个接口,将收购信息和鉴定信息分离开来,不作耦和。

与 SRP 的比较

SRP 原则说的是一个类只能有一个改变的理由,ISP 原则指的是使用方不应该依赖它不使用的方法。有的设计符合 SRP 原则却并不符合 ISP 原则。

举一个例子,正常的 Stack 都有 push pop 方法,如果使用方有一个使用场景,只能使用 push, 不能使用 pop, 那么使用方就不能继承 Stack 来实现自己的功能,与 ISP 原则相悖。但是原始的 Stack 设计是完全符合 SRP 原则的,push 与 pop 就是它自己的职责。

从这个例子可以看出,ISP 原则不仅仅能指导我们分离接口,还能帮助判断一个类的继承是不是合理的。

可能有的人觉得这个例子牵强,谁会限制一个 Stack 不能有 pop 方法。大家可以去看下Java 中的 Stack 实现,它继承了Vector ,而 Vector 是一个 List, Stack 应该只能压入弹出的,但是却继承了 List 的 add,remove,get 等方法,是一个很糟糕的实现设计。

总结

接口分离原则与单一职责原则挺相近,但在某些点上是有区别的。日常编码实现某个接口、继承某个类时,问问自己,这样符合 ISP 原则么?

设计模式以往文章链接

设计原则之里氏替换原则(LSP)

设计原则之开闭原则(OCP)

设计原则之单一职责原则(SRP)

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页