Reputation: 433
Is my implementation of Figure 12-1 correct?
This is an implementation of Interface Pollution example from Uncle Bob's book Agile Principles Patterns and Practices in C#.
I have tried implementing it as following:-
using System;
namespace AgilePrinciplesCSharp.Chapter12.Listing12_2
{
class Listing12_2
{
static void Main(string[] args)
{
var door = new TimedDoor();
var client = new Client(door);
client.TimeOut();
}
}
public interface ITimerClient
{
void TimeOut();
}
// We force Door, and therefore (indirectly) TimedDoor, to inherit from TimerClient.
public interface IDoor : ITimerClient
{
void Lock();
void Unlock();
bool IsDoorOpen();
}
// Implementation of Door Interface with Timer functionality
public class TimedDoor : IDoor
{
public bool IsDoorOpen()
{
return true;
}
public void Lock()
{
Console.WriteLine("Door Locked");
}
public void TimeOut()
{
var timer = new Timer();
timer.Register(5, this);
Console.WriteLine("Timeout! Door left open for so long");
}
public void Unlock()
{
Console.WriteLine("Door Unlocked");
}
}
// Timer class can use an object of TimerClient
public class Timer
{
public void Register(int timeout, ITimerClient client)
{
/* CODE */
}
}
// Client uses Door Interface without depending upon any particular implementation of Door
public class Client
{
IDoor door;
public Client(IDoor door)
{
this.door = door;
}
public void TimeOut()
{
door.TimeOut();
}
}
}
My doubt is in the way the implementation is described in the book, where Door is sometimes being called as a class or sometimes as an interface and i am getting confused whether i need to have a separate implementation of Door class apart from IDoor interface? Also the author does not use I notation while naming an interface which makes it even more confusing.
If anyone has read the book, i hope can understand my concern and help me out with this.
NOTE: This Book can also be read online. This discussion is at page 215. https://druss.co/wp-content/uploads/2013/10/Agile-Principles-Patterns-and-Practices-in-C.pdf
Upvotes: 0
Views: 220
Reputation: 52240
I believe he is using UML class diagram notation, so this diagram would seem to apply:
Link.
If I read this correctly, TimedDoor
should inherit from Door
. But in your example, TimedDoor
implements IDoor
. That is not consistent with the diagram.
The declaration should be:
class TimedDoor : Door
I don't think you need an IDoor
. What is germaine to the example is that Door
must implement ITimerClient
in order for a Timer
to perform operations on it. ITimerClient
should expose a single public member, Timeout()
. Presumably when the timer calls this method, the door should unlock itself, if it is a timed door. The default behavior (e.g. for a non-timed door) is probably no-operation.
interface ITimerClient
{
void Timeout();
}
class Door : ITimerClient
{
public virtual void Timeout()
{
//No operation; this isn't a timed door
}
//etc.
}
class TimedDoor : Door
{
protected bool locked = true;
public override void Timeout()
{
this.Unlock(); //Override default behavior because this type of door is timed
base.Timeout(); //Optional, sometimes recommended
}
public virtual void Unlock()
{
this.locked = false;
}
//etc.
}
Upvotes: 2