Best way to separate read and write concerns using interfaces? - c#

Lately I've been realizing the benefit of (some would argue overuse of) immutable objects to cut down dramatically on read-write dependency issues in my object model and their resulting conditions and side-effects, to ultimately make the code simpler to manage (kind of functional-programming-esque).
This practice has led me to create read-only objects that are provided values at creation/construction time and then to make available only public getters for external callers to access the properties with. Protected, internal and private setters allow internal control to be maintained over writing to the object model.
When creating interfaces while making an API over my object model, I've started considering the same issues about immutability. For example, by providing only public getters on my interfaces, and leaving it up to implementors to decide upon setters and how to handle that aspect.
An example of a "read-only" interface for implementation that I'm talking about is this Valuable Item (just for demonstration):
public interface IValuableItem {
decimal Amount {get;}
string Currency {get;}
}
However I got to wondering how I should provide a companion interface that allows for writing (and if I should), and not combine those operations within the same interface as to not "taint" its immutability.
The following ideas have come to mind, just off the top of my head. Without providing what I think are pros and cons to each, what do you think the best approach is? Is there a coding methodology common in the industry for managing this concept?
// companion writer
public interface IValuableModifier {
decimal Amount {set;}
string Currency {set;}
}
or
// explicit methods to enforce importance of or deviance in the programming
public interface IValuableModifier {
void SetAmount(decimal val);
void SetCurrency(string cur);
}
or
// companion writer that inherits the original interface
public interface IValuableModifier : IValuableItem { //...
or
// Let a concrete class choose one and/or the other.
class Concrete : IValuableModifer, IValuableItem { //...
or
etc...
What else can help me imbue writing on my otherwise immutable programming model and keep it moderately flexible or at least to separate the concerns for better control over it?

I think I might use a variant of your ideas, something like this:
public interface IValuableItem
{
decimal Amount { get; }
string Currency { get; }
}
public interface IMutableValuable : IValuableItem
{
new decimal Amount { set; get; }
new string Currency { set; get; }
}
class Item : IMutableValuable
{
public decimal Amount { get; set; }
public string Currency { get; set; }
}
This way your mutable interface has full getters and setters (I don't think it makes sense to have an interface that has setters but no getters), but any object that implements it will also have an immutable version of the interface that you can use for any pure-functional code.

You should have separate interfaces for ReadableFoo, ImmutableFoo, and MutableFoo. The latter two should inherit from the first. ReadableFoo should contain an "AsImmutable" method which will return a Foo that is guaranteed to be immutable (a immutable instance should return itself; a mutable instances should return a new immutable instance which contains its data), and probably an "AsNewMutable" member (which will create a new mutable instance containing the same data, whether the original was mutable or not).
No class should implement both ImmutableFoo and MutableFoo.

If your objects are to be immutable (and you design your application around the concept of immutable data) then objects really MUST remain immutable.
The canonical method for modifying data in immutable scenarios is to create new objects, so I would suggest something like this:
public interface IValuableItem<T>
{
decimal Amount { get; }
string Currency { get; }
T CreateCopy(decimal amount, string currency);
}
public class SomeImmutableObject : IValuableItem<SomeImmutableObject>
{
public decimal Amount { get; private set; }
public string Currency { get; private set; }
public SomeImmutableObject(decimal amount, string currency)
{
Amount = amount;
Currency = currency;
}
public SomeImmutableObject CreateCopy(decimal amount, string currency)
{
return new SomeImmutableObject(amount, currency);
}
}
SomeImmutableObject obj = new SomeImmutableObject(123.33m, "GBP");
SomeImmutableObject newObj = obj.CreateCopy(120m, obj.Currency);

Consider using a builder pattern: Builder objects construct immutable instances of the core object. .NET Strings are like this - the string object is immutable, and there is a StringBuilder class for efficient construction of string objects. (string + string + string is much less efficient than using a StringBuilder to do the same)
Note also that builder objects exist solely for building the target object - builders are not instances of the target object / do not implement the target interface themselves.
It's worth the effort to make your system run on immutable objects, as immutability washes away a lot of headaches in threading / concurrency / parallel execution scenarios, as well as data caching / data versioning scenarios.

I believe combining your 3rd and 4th choice is a better way to implement mutable & immutable types.
Public interface ImmutableItem {
decimal Amount {get;}
string Currency {get;}
}
Public interface MutableItem: ImmutableItem {
decimal Amount {set;}
string Currency {set;}
}
class Concrete : ImmutableItem {
//Only getters
}
class Concrete : MutableItem {
//Both getters & setters
}
This is clean and it let the concrete classes to decide which kind of mutability is wanted to expose to outer world.

Related

Design Pattern to use for customizable/extendable classes with constructors

Starting with the use case.
Let's consider the base for this questions is a big framework and implementations of business objects of some software.
This software hast to be customized quite regularly, so it would be preferred that most of the C# objects are extendable and logic can be overriden. Even "model data".
The goal would be to be able to write code, create objects with input parameters - that may create more objects etc - and you don't have to think about whether those objects have derived implementations in any way. The derived classes will be used automatically.
For ease of uses a typesafe way to create the objects would be preferred as well.
A quick example:
public class OrderModel
{
public int Id { get; set; }
public string Status { get; set; }
}
public class CustomOrderModel : OrderModel
{
public string AdditionalData { get; set; }
}
public class StockFinder
{
public Article Article { get; }
public StockFinder(Article article)
{
Article = article;
}
public virtual double GetInternalStock() { /*...*/ }
public virtual double GetFreeStock() { /*...*/ }
}
public class CustomStockFinder : StockFinder
{
public bool UsePremiumAvailability { get; }
public CustomStockFinder(Article article, bool usePremiumAvailability)
: base(article)
{
UsePremiumAvailability = usePremiumAvailability;
}
protected CustomStockFinder(Article article) : this(article, false) { } // For compatibility (?)
public override double GetFreeStock() { /*...*/ }
}
In both cases I wanna do stuff like this
var resp = Factory.Create<OrderModel>(); // Creates a CustomOrderModel internally
// Generic
var finderGeneric = Factory.Create<StockFinder>(someArticle);
// Typesafe?
var finderTypesafe1 = Factory.StockFinder.Create(someArticle); // GetFreeStock() uses the new implementation
var finderTypesafe2 = Factory.StockFinder.Create(someArticle, true); // Returns the custom class already
Automatically generating and compiling C# code on build is not a big issue and could be done.
Usage of Reflection to call constructors is okay, if need be.
It's less about how complicating some code generation logic, written code analyzers, internal factories, builders etc are, and more about how "easy" and understandable the framework solution will be on a daily basis, to write classes and create those objects.
I thought about tagging the relevant classes with Attributes and then generating a typesafe factory class automatically on build step. Not so sure about naming conflicts, or references that might be needed to compile, as the constructor parameters could be anything.
Also, custom classes could have different constructors, so they should be compatible at each place in default code where they might be constructed already, but still create the custom object. In the custom code then you should be able to use the full custom constructor.
I am currently considering several different cases and possibilities, and can't seem to find a good solution. Maybe I am missing some kind of design pattern, or am not able to look outside of my bubble.
What would be the best design pattern or coding be to implement use cases like this?

Interface vs. concrete object return value question

So I am trying to understand this sample code from Lynda.com without explanation.
IScore.cs
internal interface IScore
{
float Score { get; set; }
float MaximumScore { get; set; }
}
ScoreEntity.cs
internal class ScoreEntity : IScore
{
public float Score { get; set; }
public float MaximumScore { get;set;}
}
ScoreUtility.cs
internal class ScoreUtility
{
public static IScore BestOfTwo(IScore as1, IScore as2)
{
var score1 = as1.Score / as1.MaximumScore;
var score2 = as2.Score / as2.MaximumScore;
if (score1 > score2)
return as1;
else
return as2;
}
}
Calling code:
var ret = ScoreUtility.BestOfTwo(new ScoreEntity() { Score = 10, MaximumScore= 4},
new ScoreEntity() {Score = 10, MaximumScore = 6});
return;
My question is, in the ScoreUtility, what's really the benefit of using the interface type as return type in the method and argument type in the parameters, vs. just using ScoreEntity for the return and parameters, since the method itself returns a concrete object? Is this just to make the code looked 'smart'?
Any class that implements the IScore interface can be passed into the ScoreUtility method.
Perhaps there's a reason to implement another ScoreEntity class, like wanting to add a name seen in NamedScoreEntity :
internal class NamedScoreEntity: IScore
{
public string Name { get; set; }
public float Score { get; set; }
public float MaximumScore { get;set;}
}
If that's the case, then you can still use your utility methods on the new classes because of the contract the IScore interface enforces.
In this case, you could now compare the score between an un-named score object to a score object that also has a name.
Similarly, returning IScore allows the method to remain flexible enough to be used on multiple object types, and you can easily cast the returned type when you need to.
Given this declaration
public static IScore BestOfTwo(IScore as1, IScore as2)
The method does not know (or care) about the concrete types of as1 and as2. They may be ScoreEntity, or may be something entirely different. All it knows is that they implement IScore.
So if the method was to return a concrete type, then you have effectively limited the as1 and as2 parameters to being ScoreEntity, and have reduced its flexibility.
The only way you could guarantee that the method wouldn't fail would be to rewrite it as
public static ScoreEntity BestOfTwo(ScoreEntity as1, ScoreEntity as2)
In the posted code there is very little benefit, and I would argue that the interface should be removed. I would also argue that the comparison logic probably should be part of the object, or possibly an implementation of IComparer<T>.
Interfaces are most useful when there is a good reason for having multiple implementations. IComparer<T> is a great example, you might want to compare scores by the absolute score value, or the relative. So providing an abstraction is really useful.
Just applying interfaces to all classes is not a good idea, it will just make your code more complicated without any benefit. You might also discover that it can be difficult to provide a second implementation if the interface is not designed at the right abstraction level. This may result in adding properties or methods to objects that does not do anything or throws, just because they are required by a implemented interface. See for example IList<T> where many of the implementer throw exceptions for some of the methods.
In the specific case of IScore, it may be useful if you have some need for additional score-classes. But in many cases I would argue that composition might be more useful, i.e.
public class MyNamedScore{
public string Name {get;}
public ScoreEntity Score {get;}
}

Refactoring an interface exposing several possible behaviors but only one can be ever called per instantiation context

Sorry for the lenghty post. I tried to show my attempts and thought process as much as possible.
I got an interface exposing several possible behavior, but there is only one implementation of this interface that is instantiated and only one of the exposed method that can be called in each context where the interface is realized.
This interface will be used in very different context of an application and I wish to avoid exposing method that can't be called.
I wish to find a way so that the caller of IRescheduler would only know one behavior despite different method signatures. I'll detail and example and what I tried so far
public interface IRescheduler
{
AmountByTimeInterval RescheduleTomorrow(Amount amount);
AmountByTimeInterval RescheduleAtGivenDate(Amount amount, DateTime rescheduleDate);
// there will probably be more date strategies in the future
}
AmountByTimeInterval contains an Amount and a TimeInterval associates a string with a timespan from the current date. For example "1Day" would be the timespan from tomorrow to tomorrow and "1Year" would starts a year from now and ends a year later.
public class AmountByTimeInterval
{
public Amount Amount { get; private set; }
public TimeInterval TimeInterval { get; private set; }
public AmountByTimeInterval(Amount amount, TimeInterval timeInterval)
{
Amount = amount;
TimeInterval = timeInterval;
}
}
public class Amount
{
public double Value { get; private set; }
public string Currency { get; private set; }
public Amount(double amount, string currency)
{
Value = amount;
Currency = currency;
}
}
public class TimeInterval
{
public string Name { get; private set; }
public DateTime StartDate { get; private set; }
public DateTime EndDate { get; private set; }
public TimeInterval(string name, DateTime startDate, DateTime endDate)
{
Name = name;
StartDate = startDate;
EndDate = endDate;
}
}
For the sake of this example, let's suppose an IRescheduleAmountCalculator interface that takes Amount to make other Amount
public interface IRescheduleAmountCalculator
{
Amount ComputeRescheduleAmount(Amount amount);
}
Here is an example implementation of my IRescheduler interface. I got a repository pattern that gets me the TimeInterval associated to the DateTime.
public interface ITimeIntervalRepository
{
TimeInterval GetTimeIntervalByName(string name);
TimeInterval GetTimeIntervalByDate(DateTime date);
}
public class Rescheduler : IRescheduler
{
private const string _1Day = "1Day";
private readonly ITimeIntervalRepository _timeIntervalRepository;
private readonly TimeInterval _tomorrow;
private readonly IRescheduleAmountCalculator _calculator;
public Rescheduler (ITimeIntervalRepository timeIntervalRepository, IRescheduleAmountCalculator calculator)
{
_calculator = calculator;
_timeIntervalRepository = timeIntervalRepository;
_tomorrow = timeIntervalRepository.GetTimeIntervalByName(_1Day);
}
public BucketAmount RescheduleTomorrow(Amount amount)
{
Amount rescheduledAmount = _calculator.ComputeRescheduleAmount(amount);
return new TimeInterval(_tomorrow, transformedAmount);
}
public AmountByTimeInterval RescheduleAtGivenDate(Amount amount, DateTime reschedulingDate)
{
TimeInterval timeInterval = _timeIntervalRepository.GetTimeIntervalByDate(reschedulingDate);
Amount rescheduledAmount = _calculator.ComputeRescheduleAmount(amount);
return new TimeInterval(timeInterval, transformedAmount);
}
}
I don't know beforehand the context in which IRescheduler would be called, it is meant to be used by many components. Here is an abstract class I intend to provide and an example of specific implementation
public abstract class AbstractReschedule<TInput, TOutput>
{
private readonly ITransformMapper<TInput, TOutput> _mapper;
protected readonly IRescheduler Rescheduler;
protected AbstractReschedule(IMapper<TInput, TOutput> mapper, IRescheduler rescheduler)
{
_mapper = mapper;
Rescheduler = rescheduler;
}
public abstract TOutput Reschedule(TInput entityToReschedule);
protected TOutput MapRescheduledEntity(TInput input, TimeInterval timeInterval)
{
return _mapper.Map(input, timeInterval);
}
}
public class RescheduleImpl : AbstractReschedule<InputImpl, OutputImpl>
{
public RescheduleImpl(IRescheduleMapper<InputImpl, OutputImpl> mapper, IRescheduler rescheduler) : base(mapper, rescheduler)
{
}
public override OutputImpl Reschedule(InputImpl entityToReschedule)
{
AmountByTimeInterval rescheduledAmountByTimeInterval = Rescheduler.RescheduleTomorrow(entityToReschedule.AmountByTimeInterval.Amount);
return Map(entityToReschedule, rescheduledAmountByTimeInterval);
}
}
public interface IMapper<T, TDto>
{
TDto Map(T input, AmountByTimeInterval amountByTimeInterval);
}
Forcing an interface on TInput generic parameter is out of question, as the component is meant to be used in a large number of bounded contexts. Each future user of this whole rescheduling component would implement its own implementation of AbstractReschedule and IMapper.
I tried a strategy pattern but the different method argument blocked me as I couldn't define an interface contract that would allow all behaviour without exposing the actual implementation of IRescheduler.
Then I implemented a visitor pattern, where IRescheduler would have an Accept method and an implementation by behavior :
public interface IRescheduler
{
AmountByTimeInterval Accept(IReschedulerVisitor visitor, Amount amount);
}
public class RescheduleTomorrow : IRescheduler
{
public AmountByTimeInterval Accept(IReschedulerVisitor visitor, Amount amount)
{
return visitor.Visit(this, amount);
}
}
public class RescheduleAtGivenDate : IRescheduler
{
public AmountByTimeInterval Accept(IReschedulerVisitor visitor, Amount amount)
{
return visitor.Visit(this, amount);
}
}
As you noticed, the DateTime is not present here, because I actually inject it in the visitor, which is built by a Factory
public interface IReschedulerVisitor
{
AmountByTimeInterval Visit(RescheduleTomorrow rescheduleTomorrow, Amount amount);
AmountByTimeInterval Visit(RescheduleAtGivenDate rescheduleAtGivenDate, Amount amount);
}
public class ReschedulerVisitor : IReschedulerVisitor
{
private readonly ITimeIntervalRepository _timeIntervalRepository;
private readonly DateTime _chosenReschedulingDate;
private readonly IRescheduleAmountCalculator _rescheduleAmountCalculator;
private const string _1D = "1D";
public ReschedulerVisitor(ITimeIntervalRepository timeIntervalRepository, IRescheduleAmountCalculator rescheduleAmountCalculator)
{
_timeIntervalRepository = timeIntervalRepository;
_rescheduleAmountCalculator = rescheduleAmountCalculator
}
public ReschedulerVisitor(ITimeIntervalRepository timeIntervalRepository, IRescheduleAmountCalculator rescheduleAmountCalculator, DateTime chosenReschedulingDate)
{
_timeIntervalRepository = timeIntervalRepository;
_chosenReschedulingDate = chosenReschedulingDate;
_rescheduleAmountCalculator = rescheduleAmountCalculator
}
public AmountByTimeInterval Visit(RescheduleTomorrow rescheduleTomorrow, Amount amount)
{
TimeInterval reschedulingTimeInterval = _timeIntervalRepository.GetTimeIntervalByName(_1D);
Amount rescheduledAmount = _rescheduleAmountCalculator(amount);
return new AmountByTimeInterval(reschedulingTimeInterval, rescheduledAmount);
}
public AmountByTimeInterval Visit(RescheduleAtGivenDate rescheduleAtGivenDate, Amount amount)
{
TimeInterval reschedulingTimeInterval = _timeIntervalRepository.GetTimeIntervalByDate(_chosenReschedulingDate);
Amount rescheduledAmount = _rescheduleAmountCalculator(amount);
return new AmountByTimeInterval(reschedulingTimeInterval, rescheduledAmount);
}
}
public interface IRescheduleVisitorFactory
{
IRescheduleVisitor CreateVisitor();
IRescheduleVisitor CreateVisitor(DateTime reschedulingDate);
}
public class RescheduleVisitorFactory : IRescheduleVisitorFactory
{
private readonly ITimeIntervalRepository _timeIntervalRepository;
public RescheduleVisitorFactory(ITimeIntervalRepository timeIntervalRepository)
{
_timeIntervalRepository = timeIntervalRepository;
}
public IRescheduleVisitor CreateVisitor()
{
return new RescheduleVisitor(_timeIntervalRepository);
}
public IRescheduleVisitor CreateVisitor(DateTime reschedulingDate)
{
return new RescheduleVisitor(_timeIntervalRepository, reschedulingDate);
}
}
Finally (sorry for lengthy post), the RescheduleImpl that every user would have to implement would become like this :
public class RescheduleImpl : AbstractReschedule<InputImpl, OutputImpl>
{
public RescheduleImpl(IRescheduler rescheduler, IRescheduleVisitorFactory visitorFactory, IRescheduleMapper<InputImpl, OutputImpl> mapper)
: base(cancel, visitorFactory, mapper) {}
public override OutputImpl Reschedule(InputImpl entityToReschedule)
{
AmountByTimeInterval rescheduledAmountByTimeInterval = rescheduler.Accept(visitorFactory.CreateVisitor(), entityToReschedule.AmountByTimeInterval.Amount);
// the second case would be :
// AmountByTimeInterval rescheduledAmountByTimeInterval = rescheduler.Accept(visitorFactory.CreateVisitor(entityToReschedule.Date), entityToReschedule.AmountByTimeInterval.Amount);
return Mapper.Map(entityToReschedule, rescheduledAmountByTimeInterval);
}
}
While this works, I'm quite unhappy with the solution. I feel like the implementer of my solution would decide of the rescheduling strategy twice. The first time when chosing the implementation of IRescheduler to use build the last RescheduleImpl class I showed, and a second time when deciding which method of the factory to call.
I'm currently out of ideas and open to any that could solve the original problem. I'm also open to totally different implementation than my visitor + factory attempt.
Thank you for taking the time to read or answer my problem.
I think the fundamental reason why this has gotten so complicated is this:
I got an interface exposing several possible behavior, but there is only one implementation of this interface that is instantiated and only one of the exposed method that can be called in each context where the interface is realized.
Here's a way of rephrasing that:
I need different behaviors in different contexts, but I want them to all be in one interface.
The answer is not to do that. If you need one behavior here and a different behavior there, it's better to define one interface for the behavior you need here and another for what you need there.
This relates to the Interface Segregation Principle. Roughly it says that we shouldn't have one class depend on an interface but only use some if its members. When a class depends on an interface, that interface should only contain what the class needs.
If you put all of these behaviors in one interface, then it's likely to be implemented in one big class. And then every time you need another behavior, you add it to that interface, which means the class that implements it has to change. If that one class is used (to do entirely different things) by lots of other classes, then every change to the one class has potential to affect the others.
Or you might get part of the way through and realize that you want to re-architect this. You might see some way to simplify or improve. But then the same thing happens. Lots of classes depend on this interface for different reasons, so now your one change impacts lots of classes.
Or, in plainer terms: I wrote this class. I use parts of it in ten other classes. The next class I want to use it with needs something slightly different. So to meet the needs of one class, I'm going to modify the interface (and implementation) that ten other classes depend on. That might mean having to change all those classes, and I shouldn't have to change ten classes because of one. Or the change might accidentally break the other ten classes.
Those are ripple effects, and the ISP helps us to minimize them so that changing one thing doesn't affect or make us change other things.
If there are distinct behaviors and different classes need different ones, then it's better to "segregate" those interfaces, giving each class only what it needs. One way to accomplish that is to define each interface from the perspective of the class or classes that need them.
Sometimes we might try to pile more into one class so that the different types of behaviors can share some functionality or code, but there are other ways to accomplish that. If we find that two of these implementations need something similar or identical then we can just that duplicated part into a separate class and then both implementations depend on that.
Another reason why that approach is helpful is because it leads us to only write the code we need right now. Then as we write one, two, three classes, we might discover the commonalities and opportunities for reuse and refactor. That goes much more smoothly than if we try to plan for that commonality up front, write code based on that, and then once we start using it in other classes we discover that it wasn't what we needed.
#ScottHannen is correct that the problem relates to interface segregation. You are lucky that you have current requirements that demonstrate the problem right now, instead of finding out later and having to change a whole lot of deployed code.
But identifying the violated SOLID principle is not the same as fixing the problem, and I think you need a more practical answer, so:
Since different contexts can require different services from the reschedulers they use, you shouldn't try to force all reschedulers to use the same interface. You have identified two different kinds right now, but there's no reason there can't be more later.
Now, you may be thinking that you should split your IRescheduler into INextDayRescheduler and IFutureRescheduler, or whatever, and leave room for arbitrary others later on, BUT an arbitrary interface provides no value, so what this really means is that you should remove the requirement for the IRescheduler interface, since there is really no such interface at all.
You consume this interface in the AbstractReschedule constructor, but AbstractReschedule doesn't use it. So just stop that. Remove the constructor argument or (if you're omitted important code) take a different interface that gives it just what it needs.
With this one change, implementors of AbstractReschedule can just do it however they want and your problem is solved.
If there are many implementors that could use an INextDayRescheduler, or whatever, then go ahead and make a some handy utility classes that can make those common use cases easier to handle, but always bear in mind that these are utility classes that clients can chose to use, or not, according to their whims, instead of being requirements of your API.

Dependency injection & constructor madness revised

After reading this question How to avoid Dependency Injection constructor madness? I still have some concerns about my application design. Suppose I have a class which takes few parameters in its constructor:
public class SampleViewModel
{
public SampleViewModel(IReader1 reader1, IReader2 reader2, IReader3 reader3)
{
// ...
}
}
IReaderX is an interface for retrieving data from different sources and looks like this:
public interface IReader1
{
int Value1 { get; }
string Value2 { get; }
}
Now, if I wanted to aggregate this interfaces into one, I would have to create another class, say ReaderManager, which would act as a wrapper for underlying classes properties. Lot of plumbing code. Not good, if you ask me.
I tried using Composition and having all readers as properties in ReaderManager class, but then I would violate Law of Demeter if I attempted to use these readers outside.
So the question is: how should I decrease number of constructor dependencies which do not communicate with each other and only expose properties, not internal logic?
Look at it from a couple of different perspectives: the consumer, and a higher-level design.
From the perspective of `SampleViewModel`
Does it not like having so many collaborators? Maybe if it had its druthers, it would only have a single collaborator. How would that collaborator look? Create an interface to represent the role for it.
For example:
public interface ISampleViewModelReader
{
int Value1 { get; }
string Value2 { get; }
double Value3 { get; }
string Value4 { get; }
}
public class AggregatedSampleViewModelReader : ISampleViewModelReader
{
public AggregatedSampleViewModelReader(IReader1 reader1, IReader2 reader2, IReader3 reader3)
{
// ...
}
// ...
double Value3 { get { return reader2.Value3; } }
// ...
}
public class SampleViewModel
{
public SampleViewModel(ISampleViewModelReader reader)
{
// ...
}
}
You indicated that you have a concern about this approach, since it would involve a "lot of plumbing code". But consider that this plumbing code is going to exist with or without a wrapper class. By defining a wrapper class, at least you're identifying an object whose sole responsibility is to handle this plumbing, rather than mixing it into the other responsibilities of the SampleViewModel.
From a higher-level design perspective
How do other objects use the IReaderX objects? Are IReader1, IReader2, and IReader3 often used together? How about IReader1 and IReader3?
The point of asking this question is to identify "hidden" abstractions so that they can be made more explicit. If certain objects are often used in tandem, it's usually representative of a broader design concept.
But sometimes a rose is a rose is a rose. Maybe SampleViewModel is the only thing that uses the IReaderX objects. Perhaps SampleViewModel's sole responsibility is to aggregate the individual readers. In these types of cases, there's nothing wrong with having several collaborators.
If another collaborator is added later on (e.g., IReader4), then all of this evaluation should take place again. Sometimes design just happens to jump out at you.

Should entities implement interfaces?

I personally don't have my entities implement interfaces. For a Task class I wouldn't have ITask that just had the same properties defined on it.
I've seen it done a few times though, so I'm wondering where that advice comes from, and what benefits you get from it.
If you're using an ORM then the argument that says "I can change my data access" is irrelevent, so what other reason is there for doing this?
UPDATE:
A good point was made in the comments about INotifyPropertyChanged. That wasn't my point though - I'm talking about having something like this:
public interface ITask
{
int Id { get; set; }
string Description { get; set; }
}
public class Task : ITask
{
public int Id { get; set; }
public string Description { get; set; }
}
I went down this road once (interfaces for value objects). It was a royal pain in the backside, I recommended against it. The common arguments for it are:
Mocking:
They are value objects. Nought to mock. Plus mocking ends up being a large pain than either writing a builder (in Java) or using the named arguments stuff in C#.
Readonly views:
I must admit I still prefer to make something immutable by default, only making it mutable if absolutely required.
Hidden functionality:
Generally scope has covered this one for me.
The major benefit of this is that it is a way of exposing your entity as a "read-only" version (as long as your interface does not expose setters of course).
We're doing quite a bit of unit testing and so often want to mock out things we're not testing. Although I don't like it, we've ended up using interfaces all over the place because it makes it a lot easier to mock things.
In theory most of the mocking frameworks can mock normal classes too, but in practice this has caused us issues because we sometimes do clever things with reflection and the type of the mocked class isn't the same as the original. So doing:
var myTask = MyIoCProvider.Get<Task>();
var taskType = typeof(myTask);
Was unpredictable. Whereas:
var myTask = MyIoCProvider.Get<ITask>();
var taskType = typeof(myTask);
Gives you as taskType that IS definitely derived from ITask.
So interfaces just give us a way of making our system more mockable.
If you were thinking in terms of using DomainEvents than data structures such as the task really do need to implement an interface
public interface IDomainEvent
{
Guid EventId { get; }
Guid TriggeredByEvent { get; }
DateTime Created { get; }
}
public class OrderCancelledEvent : IDomainEvent
{
Guid EventId { get; set; }
Guid TriggeredByEvent { get; set; }
DateTime Created { get; set; }
// And now for the specific bit
int OrderId { get; set; }
}
Or similarly if you have a common data access layer that may need to take in a standard base class of IEntity but I wouldn't have an interface for each type if it is just a data structure as you describe in your post.
When you are handling Domain Objects that actually expose behaviour you may then want to have an interface for unit testing.
I think some programmers just use interfaces, because they heard interfaces are good so they ended using them everywhere without thinking about actual pros and cons.
Me personally, I never use interfaces for entities that only represent a piece of data like db row for example.

Categories

Resources