4

我有一个预订系统,可让您预订、修改现有预订和取消现有预订。我正在研究接口隔离原则,我想知道我的接口应该有多薄,以及我是否违反了单一责任原则。我最初的设计是:

interface IReservation
{
     void Book();
     void Modify();
     void Cancel(); 
}

但后来我想,如果一个预订系统不需要为预订实现这些方法之一,并且只关心预订,例如,我做了以下事情:

interface IBook
{
     void Book();
}


interface IModify
{
    void Modify();
}

interface ICancel
{
    void Cancel();
}

现在我可以做这样的事情:

interface IReservation : IBooking
{


}

或者

interface IReservation : IBooking, IModify
{


}

所以问题就变成了我是不是把它像这样细化了。此外,为接口考虑名称变得更加困难,例如,我不喜欢 IModify 或 ICancel (它们对我来说就像应该在 IReservation 接口上的方法)。您如何确定应该进入接口的内容以及应该将哪些内容隔离到另一个接口、类等中...

4

3 回答 3

5

在查看接口的范围时,您必须考虑两件事:

  1. IReservation要求每个人都实现这些成员是否有意义?
  2. X在没有 member 的情况下引用 member 是否有意义Y

第一个是您所涵盖的内容,并得出了“否”的结论。第二个同样重要。将某些东西视为“可以修改”而它不能做任何其他事情是否有意义?如果没有,请考虑制作IReservationandIModifiableReservation或其他一些功能分组。

例如,它看起来像CancelModify牵手,所以可能想把它们放在一起IModifiableReservation,然后让你的类实现那个接口。

正如你所拥有的,这似乎有点太细化了。

于 2011-10-21T20:58:54.113 回答
1

我建议有两个接口

interface IBookableReservation
{
     void Book();
}

正如亚当罗宾逊所  建议的那样

interface IModifiableReservation
{
   void Modify();
   void Cancel();
}

您不需要创建 IReservation 接口,而是直接从 IBookableReservation 和 IModifiableReservation 继承您的类。客户端可以使用一个或两个接口。

没有必要创建一个接口,它只是复制单个类的公共方法。如果接口与类同名只是带有“I”前缀,这是代码异味,因为它表明接口和实现 它的具体类之间是 1:1 的关系。

请参阅重用抽象原则 (RAP)

并来自 http://martinfowler.com/bliki/InterfaceImplementationPair.html

当你不打算有多个实现时使用接口是保持一切同步的额外努力。此外,它隐藏了你实际提供多个实现的情况。

于 2013-05-10T23:43:09.210 回答
0

如果您的应用程序确实需要支持不同类型的预订,并且稍后一些通用逻辑应该能够处理所有这些 - 我建议为每种服务类型引入单独的接口,并为每个预订本身引入单个接口,这个想法 - 预订提供一组服务,因此您可以只公开由通用接口抽象的服务列表,IReservationService并摆脱每个预订系统的多个接口实现。只需为每个服务创建一个类并通过 ctor of Reservation 注册服务:

var reservationWithBooking = 
     new Reservation(new List<IReservationService { new BookingService() });

var reservationWithCancellation = 
     new Reservation(new List<IReservationService { new CancellationService(); });

var mixedReservation = 
     new Reservation(new List<IReservationService 
                            {
                                new BookingService(),
                                new CancellationService()
                            });

接口:

interface IReservationService
{       
}

interface IBookingService : IReservationService
{
   void Book(...);
}

interface ICancellationService : IReservationService
{
   void Cancel(...);
}

interface IReservation
{
   IEnumerable<IReservationService> Services { get; }
}

class Reservation : IReservation
{
    private IList<IReservationService> services;

    public Reservation(IEnumerable<IReservationService> services)
    {
       this.services = new List<IReservationService>(services);
    }

    public IEnumerable Services<IReservationService> 
    { 
       get 
       {
          return this.services;
       }
    }
}
于 2011-10-21T20:58:14.417 回答