2

接口隔离原则如何应用于便利/辅助方法?例如:

我想创建一个代表业务合作伙伴的界面。我需要的最低限度是一个 setter 和一个 getter 方法,它们可以设置或获取整个合作伙伴列表:

Interface Partners {
  method getList();
  method setList();
}

我还想要一个 contains() 方法来告诉我某个人是否包含在合作伙伴列表中。我认为这是一个帮助或便利方法,因为它所做的一切都是调用 getPartners() 然后检查给定的人是否在该列表中。

我对接口隔离原则的理解是我应该将我的 contains() 方法分离到一个单独的接口中,因为有人可能想要实现我的 Partners 接口而不为这个不必要的辅助方法提供实现。在我的示例中,这没什么大不了的,但是辅助方法的列表会很快变长(addPartner、addPartnerByID、addPartnerByUserid 等),所以这是一个实际问题。

我担心的是,我发现很难为一个接口选择一个名称来保存我的 contains() 方法,这听起来并不麻烦,而且我认为任何时候你在命名某些东西时遇到这么多麻烦,这是一个危险信号你的设计有问题。拥有一个名为 PartnersSupportingSetInclusionChecks 的接口似乎并不合适,拥有一个仅名为 PartnerHelperMethods 的接口似乎也不好。

如何将接口隔离原则应用于此类方法?

4

2 回答 2

1

因为有人可能想要实现我的合作伙伴接口而不提供这种不必要的帮助方法的实现

强调我的

contains()如果你认为在你的 API 中有一个方法很重要,请一定要有一个方法。特别是如果您的所有客户端代码当前都使用一个。

接口隔离原则是将完全不相关的方法排除在接口之外。看起来您正在尝试实现一个Repository应该具有获取、包含等方法的方法,以查看存储库中有哪些元素以及检索它们的方法。

如果您有其他与获取或设置合作伙伴无关的方法,则应应用 ISP 为其创建不同的接口。

但是,如果您认为您的客户端将此存储库视为只读并且不应允许修改它,但您没有,您可能需要考虑将获取/包含方法与设置/添加方法分开至。

于 2015-10-20T17:46:45.477 回答
0

以下答案基于 C# 语言。它可能在另一种语言中无效。

我想创建一个代表业务合作伙伴的界面

这第一句话告诉我,您可能不需要接口,而是需要一个顶级抽象类。区分我们需要接口还是抽象类非常重要。

抽象类代表层次结构,该层次结构的每个后代都是一个专业化,因此您可以添加更多成员以丰富家庭。在这种情况下,关系描述了“这个 X是一个Y”</p>

接口代表一组与任何层次结构无关的特征和行为。因此,主要目的是链接具有相同特征或行为的不同类型的类。这种关系描述了“这个 X可以做Y”</p>

因此,假设更适合您的描述的是抽象类,我建议如下:

一种选择可以将方法“getList()”和“setList()”设置为非抽象方法,并在抽象类中提供一个字段来存储列表

public abstract Partner
{
      List<Partner> list;

      public void SetList(List<Partner> list)
      {
          list = list;
      }
      public List<Partner> GetList(Partner partner)
      {
          return list;
      }
}

因此,“包含”方法也可以是非抽象的,因此您不必强制后代类提供实现。

public bool Contains(Partner partner)
{
    return list.Contains(partner);
}

让我们假设将来您想添加新的辅助方法。这些方法可以是基类中的新非抽象方法,因此您不会影响“合作伙伴”的当前后代。

如果您需要修改辅助方法的实现,可以将其设置为“虚拟”,以便后代类可以覆盖基本实现。

public virtual void AddPartner(Partner partner)
{
    list.Add(partner);
}
于 2018-08-27T14:33:22.953 回答