接口隔离原则如何应用于方便/辅助方法? 例如:
我想创建一个表示业务合作伙伴的接口。 我需要的最低限度是一个二传手和一个 getter 方法,用于设置或获取整个合作伙伴列表:
Interface Partners {
method getList();
method setList();
}
我还想有一个contains((方法来告诉我某个人是否包含在合作伙伴列表中。 我认为这是一个帮助程序或方便的方法,因为它所做的只是调用getPartners((,然后检查给定的人是否在该列表中。
我对接口隔离原则的理解是,我应该将我的 contains(( 方法分离到一个单独的接口中,因为有人可能想要实现我的合作伙伴接口,而不为这个不必要的帮助程序方法提供实现。 在我的示例中,这没什么大不了的,但是帮助程序方法的列表可能会很快变长(addPartner,addPartnerByID,addPartnerByUserID等(,所以这是一个实际问题。
我担心的是,我发现很难为一个听起来不麻烦的接口选择一个名称来保存我的 contains(( 方法,而且我认为任何时候你在命名某些东西时遇到这么多麻烦,这是一个危险信号你的设计有问题。 拥有一个名为 PartnersSupportingSetInclusionChecks 的接口似乎不对,拥有一个名为 PartnerHelperTMethods 的接口似乎也不好。
如何将接口隔离原则应用于此类方法?
因为有人可能想要实现我的合作伙伴接口,而不为这个不必要的帮助程序方法提供实现
强调我的
如果您认为在您的 API 中拥有它很重要,请务必使用contains()
方法。 特别是如果您的所有客户端代码当前都使用一个。
隔离原则是将完全不相关的方法排除在接口之外。 看起来您正在尝试实现一个应该具有get,包含等方法的Repository
,以查看存储库中有哪些元素以及检索它们的方法。
如果您有其他类型的方法与获取或设置合作伙伴无关,则应应用 ISP 为此制作不同的接口。
但是,如果您认为会有客户端将此存储库视为只读并且不应允许修改它,则可能需要考虑将获取/包含方法与设置/添加方法分开,但您不必这样做。
以下答案基于 C# 语言。它可能在另一种语言中无效。
我想创建一个代表业务合作伙伴的接口
第一句话告诉我,你可能不需要接口,而需要一个顶级抽象类。区分我们是否需要接口或抽象类非常重要。
抽象类表示层次结构,其中该层次结构的每个后代都是一个专用化,因此您可以添加更多成员以丰富族。在本例中,关系描述"此 X 是 Y">
接口表示一组未链接到任何层次结构的特征和行为。因此,主要目的是链接具有相同功能或行为的不同类型的类。 关系描述"这个X可以做Y">
因此,假设更适合您的描述的是抽象类,我建议如下:
一种选择是将方法"getList(("和"setList(("设置为非抽象方法,并在抽象类中提供一个字段来存储列表
public abstract Partner
{
List<Partner> list;
public void SetList(List<Partner> list)
{
list = list;
}
public List<Partner> GetList(Partner partner)
{
return list;
}
}
因此,方法"Contains"也可以是非抽象的,因此您不会强制后代类提供实现。
public bool Contains(Partner partner)
{
return list.Contains(partner);
}
假设将来要添加新的帮助程序方法。这些方法可以是基类中的新的非抽象方法,因此不会影响"Partner"的当前后代。
如果需要修改帮助程序方法的实现,可以将其设置为"虚拟",以便后代类可以重写基实现。
public virtual void AddPartner(Partner partner)
{
list.Add(partner);
}