What is the thin line between thin and bold?

I have a reservation system that allows you to reserve a reservation, modify an existing reservation and cancel an existing reservation. I studied the principle of separation of segregation, and I was wondering how subtle I have to deal with my interfaces, and if I violate the principle of sole responsibility. My internal design was:

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

but then I thought that if one reservation system does not need to implement one of these methods for reservation and, for example, just deals with booking, so I did the following:

 interface IBook { void Book(); } interface IModify { void Modify(); } interface ICancel { void Cancel(); } 

Now I can do something like this:

 interface IReservation : IBooking { } 

or

 interface IReservation : IBooking, IModify { } 

So the question is that I take it for a long time, draining it like that. In addition, it becomes more difficult to think of names for the interface, for example, I do not like IModify or ICancel (they just seem to me to be methods that should be in the IReservation interface). How do you determine what should go into an interface and what should be allocated to another interface, class, etc.

+4
source share
3 answers

You have two things to consider when considering the capabilities of your interfaces:

  • Does it make sense for each IReservation implement these elements?
  • Does it make sense to refer to an element X without a member Y ?

The first is what you reviewed and came to the conclusion "No." The second, though equally important. Does it make sense to think of something that โ€œcan changeโ€ without being able to do anything else? If not, consider creating IReservation and IModifiableReservation or some other grouping of functionality.

For example, it seems that Cancel and Modify go hand in hand, so you might want to put them together in IModifiableReservation , and then implement your interface in this class.

As you have it, it seems a little too granular.

+5
source

I suggest having two interfaces

 interface IBookableReservation { void Book(); } 

and as suggested by Adam Robinson

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

You do not need to create an IReservation interface, but inherit your class directly from IBookableReservation and IModifiableReservation. Clients can use one or both of these interfaces.

It makes no sense to create an interface that simply duplicates the public methods of one class. If the interface has the same name as the class, only with the prefix "I", this is the smell of code, because it indicates that it is a 1: 1 ratio between the interface and the specific classes that implement it .

See Principle of Repeated Abstractions (RAP)

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

Using interfaces when you are not going to have multiple implementations is an extra effort to keep everything in sync. In addition, it hides cases where you really provide multiple implementations.

+1
source

If your application really needs to support different types of redundancy, and then some common logic should be able to handle all of them - I would suggest introducing a separate interface for each type of service and one interface for each reservation, the idea is that the reservation provides a set of services, so you can just browse through the list of services abstracted by the common IReservationService interface, and get rid of the implementation of several interfaces for each backup system. Just create one class per service and register services through ctor 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() }); 

Interfaces:

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

All Articles