I'm currently implementing the Command-Handler Pattern for a service I'm designing where the Command is essentially a DTO for the Handler's .Handle() method. As I begin to implement various concrete classes I realize that in order to satisfy the Open/Closed Principle and Single Responsibility Principle I may end up with thousands of Command and Handler classes, which would significantly violate the Don't Repeat Yourself Principle.
For example, part of the process I'm encapsulating requires deleting all data by ProjectId from 60 odd tables to reset them. If I implement each one as an atomic concrete Command object and concrete CommandHandler object then I'll have 120 classes just for this first step. They will all perfectly follow SRP & OCP, however DRY takes a serious beating...
public class DeleteProjectLogCommand : CommandBase
{
public long? ProjectId { get; set; }
}
public class DeleteProjectLogCommandHandler : ICommandHandler<DeleteProjectLogCommand>
{
public async Task<Feedback<DeleteProjectLogCommand>> Handle(DeleteProjectLogCommand command, CancellationToken token)
{
// ...
}
}
Alternatively I could implement a single, multipurpose, command and handler class and a ProjectTables enumeration could be used in place of all the discrete classes.
public class DeleteTableByProjectIdCommand : CommandBase
{
public DeleteTableByProjectIdCommand(ProjectTables table, long? projectId) {}
public long? ProjectId { get; set; }
public ProjectTables Table { get; set; }
}
public class DeleteTableByProjectIdCommandHandler : ICommandHandler<DeleteTableByProjectIdCommand>
{
public async Task<Feedback<DeleteTableByProjectIdCommand>> Handle(DeleteTableByProjectIdCommand command, CancellationToken token)
{
switch(command.Table)
{
case ProjectTables.ProjectLog:
// x60 tables
break;
}
}
}
However this would violate the Open/Closed Principle because if a new table is added, both the enumeration and every place that uses it, would have to be updated as well. Not to mention the smell you get from a 60-case switch statement.
Sooo... who wins? DRY or SRP & OCP?
Don't get too tied up with acronyms. Concentrate on writing code that feels right. Atomic commands are a very good idea, but you need the right level of granularity I generally consider a command to be a complete (user) operation.
Your design of an enum and a God switch fails a basic sanity test and is not extensible without modifying the class itself, so it must be bad, right?
Consider using a RelayCommand: http://msdn.microsoft.com/en-us/magazine/dn237302.aspx
This is a command that implements ICommand, but expects to have a delegate injected for the actual work. A number of MVVM frameworks include a RelayCommand (or DelegateCommand) out of the box.
So, you implement your command interface, and demand that an Action, or an Action<T> be injected in the ctor. Execute triggers the action. If you need to pass something to the action, you can use the "ofT" version, or enclose it in the delegate that you pass.
This allows you to:
Have a single implementation of Command (or 2, if you support a generic)
Put the actual command logic somewhere else (like in your domain object)
If it makes sense, the command logic can actually be a Private member of your domain class, exposed by the command because you passed the delegate.
Example:
public class SomeViewModelOrDomainClass
{
public ICommand DoItCommand {get; private set;}
//ctor
public SomeViewModelOrDomainClass()
{
// if your command includes a CanExecute bool, then also demand a Predicate to handle CanExecute
this.DoItCommand = new RelayCommand(() => this.SomePrivateMethod(maybeEvenAnEnclosedParam), aCanExecutePredicate);
}
}
Hundreds of commands and handlers don't violate DRY neither OCP, because a command contains an order for a specific use case i.e each command and handler are implementing a business use case. Do you have identical business use cases?
An example, I worked on an app which has different resource types. But I had only 1 DeleteCommand which looked like this
public class DeleteResource:AbstractCommand
{
public Guid ResourceId;
public ResourceType Type;
}
public class DeleteResourceHandler:IExecute<DeleteResource>
{
private IDispatchMessages _bus;
private IStoreResources _repo;
public DeleteResourceHandler(IStoreResources repo, IDispatchMessages bus)
{
_repo = repo;
_bus = bus;
}
public void Execute(DeleteResource cmd)
{
_repo.Delete(cmd.ResourceId);
var evnt = cmd.ToEvent();
_bus.Publish(evnt);
}
}
Of course this is not the whole story, because the whole app was designed to work with N resource types and this means my entity storage was mainly a key-value store which didn't care about entity structure. Delete just needs an id.
Once the resource was deleted en event is published which is handled by the read model updater which then deletes the query data for that resource type.
When adding a new resource, I don't need to touch the DeleteCommand or the DeleteHandler nor even the entity storage. But you see, the command and handler don't work alone, they're using other components which allows them to achieve DRY and OCP. And OCP is a bit fuzzy principle.
Related
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?
I'm beginning a project using Xamarin Forms for cross-platform development of a mobile app. I'm using the MVVM model, of which I have little experience of beyond a few small WPF applications.
I'm using the ICommand interface to create commands and binding to them in the view's XAML, which by default involves a good amount of duplicate code. Xamarin.Forms provides a concrete subtype, Command, of ICommand, which is used as in the discussion here, and I see two obvious ways to instantiate them.
Option #1 - Assign the Commands in the constructor.
public class Presenter : ObservableObject
{
public Presenter()
{
DoStuffCommand = new Command(DoStuff);
}
public ICommand DoStuffCommand { get; set; }
private void DoStuff()
{
// VM stuff
}
}
Option #2 - Instantiate Command in the getter
public class Presenter : ObservableObject
{
public ICommand RunCommand { get { return new Command(DoStuff); } }
private void DoStuff()
{
// VM stuff
}
}
Many view models are going to have a number of commands, and approach #2 avoids assigning all of these one by one in the constructor - when the commands action is not going to change, it's clearer to me having this action declared with the ICommand itself. On the other hand, this will create a new instance of Command every time the command fires, which is clearly less efficient memory wise than approach #1.
Does anyone have experience of this, and/or could give me an idea of whether this could impact performance noticeably? And is there a way to improve upon this, such as by manually destroying the Command objects?
Thanks!
An alternative to option #2 would be to have a backing field for it and ensures it only instantiates once:
private ICommand _doStuffCommand;
public ICommand DoStuffCommand =>
_doStuffCommand = _doStuffCommand ?? new Command(DoStuff);
private void DoStuff()
{
}
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.
I have an interface ITradingApi like so:
public interface ITradingApi
{
IOrder CreateOrder(...);
IEnumerable<Symbol> GetAllSymbols();
// ...
}
This is meant to be a facade for the different APIs of the vendors of trading software.
My view model has a dependency on this trading API in its constructor:
public class MainViewModel
{
public MainViewModel(ITradingApi tradingApi) { /* ... */ }
// ...
}
I use Ninject as an IoC container, so I will create an instance of my view model like this:
var vm = kernel.Get<MainViewModel>();
Now, my problem:
The implementation of ITradingApi might need additional parameters to work.
Example:
One vendors API uses TCP/IP internally, so I need a hostname and a port.
Another vendor uses a COM object. Here I don't need any info.
A third vendor needs username and password of the account.
In the spirit of not allowing incomplete objects, I added these as parameters to the constructors of the concrete implementations.
Now, I am not sure, how this would work. Clearly, these additional parameters do not belong into the interface, because they are specific to each implementation.
On the other hand, these additional parameters need to be entered by the end-user and then passed to the implementation of ITradingApi, meaning that the user of ITradingApi needs intimate knowledge about the concrete implementation.
How to solve this dilemma?
UPDATE:
One approach could be to create an ITradingApiProvider that exposes a list of required parameters. The View could automatically create an input form for these parameters that is databound to the parameters in ITradingApiProvider. Now, when an ITradingApi instance is requested from the provider, it can make use of these parameters to create an instance of the concrete implementation. Clearly the implementation of ITradingApiProvider and ITradingApi are tightly coupled, but I think that is not a problem as long as each implementation of ITradingApi comes with a corresponding implementation of ITradingApiProvider.
Based on the information so far put forth here, I'd like to point out one or two things:
First of all, whether or not the concrete configuration values are supplied at composition time or truly first available at runtime as user input makes a huge difference. As long as they can be resolved at composition time things are easy because you can simply read the values from the environment and supply them to the appropriate constructors. So, for the rest of this answer I'm going to assume that things are much harder and you actually need to get those values from the user at runtime.
Instead of attempting to come up with a general-purpose configuration API I'd much rather model what's actually going on. In this case it sounds to me like we're collecting configuration values from the user, so why not model this explicitly?
Product Trader
Define an interface like this:
public interface ITradingApiTrader
{
ITradingApi Create(Type apiType);
}
Here, it's assumed that apiType can cast to ITradingApi, but this can't be enforced by the compiler. (The reason I'm calling this a 'Trader' is because this is a variation of the Product Trader pattern (PLoPD 3).)
How is this different than before?
Well, you can implement the Create method by showing a user interface for each type of ITradingApi. Each concrete user interface gathers the values required for its own concrete ITradingApi implementation and subsequently returns a correctly configured instance.
If you know the concrete types at compile time, other variations include these:
public interface ITradingApiTrader
{
ITradingApi CreateMT4TradingApi();
ITradingApi CreateFooTradingApi();
ITradingApi CreateBarTradingApi();
// etc.
}
Perhaps you can also do this (although I haven't tried to compile this):
public interface ITradingApiTrader
{
ITradingApi Create<T>() where T : ITradingApi;
}
Note also that you don't need to define the first ITradingApiTrader's Create method based on a Type - any identifier (such as an enum or string) might do instead.
Visitor
If the set of ITradingApi is (finite and) known at design time, the Visitor design pattern might also offer an alternative.
If you use a Visitor, you can make the Visit method show an appropriate user interface and then subsequently use the values collected from the user interface to create the appropriate ITradingApi instance.
Basically this is just a variation on the previous 'solution' where the Product Trader is implemented as a Visitor.
Is this what your after?
ninjectKernel.Get<MainViewModel>().WithConstructorArgument("tradingApi",
kernel.Get<ITaxCalculator>() .WithConstructorArgument("additionalParameter","someValue")));
Ok my two cents, I am not sure of anything you know. It is just to help and try...
We give a visitor to your api as construction of the interface:
public interface ITradingApi
{
Object CreateOrder();
IEnumerable<Object> GetAllSymbols();
}
public class TradingApi : ITradingApi
{
IvisitorAPI _VisitorAPI;
public TradingApi(IvisitorAPI visitorAPI)
{
_VisitorAPI = visitorAPI;
}
public Object CreateOrder()
{
var Order = new Object();
//bla bla bla
//here code relative to different visitor
_VisitorAPI.SaveOrder(Order);
return Order;
}
}
It is your visitor that knows how to handle some of the action, because depending on the visitor he will use your api in different ways to achieve the same action ( here SaveOrder).
public interface IvisitorAPI
{
bool SaveOrder(Object order);
}
public class visitorApiIP : IvisitorAPI
{
public string HostName { get; set; }
public int Port { get; set; }
public visitorApiIP(string hostname, int port)
{
HostName = hostname;
Port = port;
}
public bool SaveOrder(Object order)
{
//save the order using hostname and ip
//...
//....
return true;
}
}
Only the visitor has a knowledge of what he needs to achieve his version of the action.
Therefore it is not the APi that needs additionnal parameters, we are pushing the logic away in the visitor class.
This visitor class might be created only when ewe know who is the visitor therefore, surely at runtime
Hope it might give you some perspective. I do not know if the whole theory can be applied your exact situation.
My best anyway ;)
The solution is to use the approach as outlined in the update part of my question. ITradingApiProvider takes the role of an abstract factory and thus should be renamed to ITradingApiFactory. It would expose a list of needed parameters whose values can be set. This list in turn can be used by the View to automatically present the user with an input form to enter a value for each parameter, because only the user knows the values of for the parameters.
The call to Create would then use these parameters:
public interface ITradingApiFactory
{
ITradingApi Create();
IEnumerable<Parameter> Parameters { get; }
}
public class Parameter
{
public Parameter(Type type, string name, string description)
{ Type = type; Name = name; Description = description; }
public Type Type { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public object Value { get; set; }
}
public class MT4TradingApiFactory : ITradingApiFactory
{
Dictionary<string, Parameter> _parameters;
public MT4TradingApiFactory()
{ /* init _parameters */ }
public ITradingApi Create()
{
return new MT4TradingApi(_parameters["hostname"].ToString(),
(int)_parameters["port"]);
}
IEnumerable<Parameter> Parameters { get { return _parameters.Values; } }
}
More info can be found in this answer.
This can be advanced further to make it easier to use, by giving each Factory implementation the parameters as properties and change the Parameter class to work directly on these properties using expression trees. If someone is interested in this advanced factory design, please leave a comment.
I think there is nothing wrong with your provider approach. You have two concerns here:
An operational one: your ITradingAPI which defines a contract for operations you can perform.
A meta-data one: something which describes properties of an actual implementation (meta data might not be quiet right but can't think of a better name for it)
Now apparently you need something which can make the connection between the two and that is your ITradingAPIProvider. Seems reasonable straight forward and has good chance of that you will still understand your code when coming back to it after a year ot two ;)
How about trying something similar to the strategy pattern? Create a new interface called IConnectStrategy:
interface IConnectStrategy
{
void Connect();
}
Add the connectstrategy as an argument to the method void CreateOrder(IConnectStrategy connectStrategy) in ITradingApi and let each vendor create/specify their own method for connecting. E.g. for one vendor create:
public class TCPConnectStrategy : IConnectStrategy
{
public TCPConnectStrategy(string hostName, int port)
{
/* ... */
}
public void Connect()
{
/* ... tcp connect ... */
}
}
(Connect might not be the best name or even what you are actually doing, but please apply it to whatever works for your project.)
Edit after comments:
Create a strategy that only have contracts for each method that have vendor-specific parameters. Then add a method void SetVendorStrategy(IVendorStrategy vendorStrategy) (or a property) to the ITradingAPI-interface. Each implementation of the strategy has their own constructor with their own parameters, and each method (that require vendor specific parameters) in each implementation of the ITradingAPI-interface simply calls vendorStrategy.DoSomethingWithVendorSpecificData().
I have a fairly simple system, and for the purposes of this question there are essentially three parts: Models, Repositories, Application Code.
At the core are the models. Let's use a simple contrived example:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In that same project is a generic repository interface. At its simplest:
public interface IRepository<T>
{
T Save(T model);
}
Implementations of that interface are in a separate project and injected with StructureMap. For simplicity:
public class PersonRepository : IRepository<Person>
{
public Person Save(Person model)
{
throw new NotImplementedException("I got to the save method!");
// In the repository methods I would interact with the database, or
// potentially with some other service for data persistence. For
// now I'm just using LINQ to SQL to a single database, but in the
// future there will be more databases, external services, etc. all
// abstracted behind here.
}
}
So, in application code, if I wanted to save a model I would do this:
var rep = IoCFactory.Current.Container.GetInstance<IRepository<Person>>();
myPerson = rep.Save(myPerson);
Simple enough, but it feels like it could be automated a lot. That pattern holds throughout the application code, so what I'm looking to do is create a single generic Save() on all models which would just be a shorthand call to the above application code. That way one would need only call:
myPerson.Save();
But I can't seem to figure out a way to do it. Maybe it's deceptively simple and I'm just not looking at it from the correct angle. At first I tried creating an empty ISaveableModel<T> interface and intended to have each "save-able" model implement it, then for the single generic Save() method I would have an extension on the interface:
public static void Save<T>(this ISaveableModel<T> model)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
model = rep.Save(model);
}
But it tells me that rep.Save(model) has invalid arguments. It seems that it's not wiring up the type inference as I'd hoped it would. I tried a similar approach with a BaseModel<T> class from which models would inherit:
public class BaseModel<T>
{
public void Save()
{
this = IoCFactory.Current.Container.GetInstance<IRepository<T>>().Save(this);
}
}
But the compiler error is the same. Is there a way to achieve what I'm trying to achieve? I'm very flexible on the design, so if I'm going about something all wrong on an architectural level then I have room to step back and change the big picture.
Would a generic extension method solve it?
public static T Save<T>(this T current)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
rep.Save(current);
}
You can then constrain it to your ISaveableModel<T> interface. Return type above not implemented, but you can put it to a boolean or status flag, whatever.
In both approaches, the parameter to the Save() function is not of type T. In the first one, it is ISaveableModel<T>, and in the second, it is BaseModel<T>. Since the repository is a generic based on T, Save method will expect a variable of type T. You can add a simple cast to T before you call Save to fix it.
Alternatively, your IRepostory<T> can be changed to
public interface IRepository<T>
{
T Save(ISaveableModel<T> model);
}
which makes more sense.