瘦和胖接口之间的“细线”是什么?

时间:2011-10-21 20:54:32

标签: .net oop interface solid-principles

我有一个预订系统,允许您预订,修改现有预订和取消现有预订。我正在研究接口隔离原理,我想知道我应该如何轻松地创建我的接口,如果我违反了单一责任原则。我的初步设计是:

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接口上的方法)。你如何确定接口应该进入什么以及应该将哪些内容转移到另一个接口,类等等......

3 个答案:

答案 0 :(得分:5)

在查看界面范围时,您需要考虑两件事:

  1. 要求每个IReservation实施这些成员是否有意义?
  2. 在没有成员X的情况下引用成员Y是否有意义?
  3. 首先是你所涵盖的内容,并得出“否”的结论。第二,虽然同样重要。在没有能够做任何其他事情的情况下将某些事情视为“可以修改”是否有意义?如果没有,请考虑制作IReservationIModifiableReservation,或其他一些功能组合。

    例如,好像CancelModify齐头并进,所以可能希望将它们放在IModifiableReservation上,然后让您的类实现该接口

    如你所知,这似乎有点过于细化。

答案 1 :(得分:1)

我建议有两个接口

interface IBookableReservation
{
     void Book();
}
{p>和as suggested Adam Robinson

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

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

没有必要创建一个接口,它只复制单个类的公共方法。 如果interface与具有“I”前缀的类具有相同的名称,那么它就是代码气味,因为它表明它是1:1 relationship between the interface and the concrete classes that implement它。

请参阅Reused Abstractions Principle (RAP)

http://martinfowler.com/bliki/InterfaceImplementationPair.html

  

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

答案 2 :(得分:0)

如果您的应用程序确实需要支持不同类型的预留,后来一些常见的逻辑应该能够处理所有这些 - 我建议为每个预留服务类型和单个接口引入单独的接口,这个想法 - 预留提供集合服务,所以你可以公开由公共接口IReservationService抽象的服务列表,并摆脱每个预订系统的多个接口实现。只需为每个服务创建单个类,并通过预订部门注册服务:

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;
       }
    }
}