This question is a result of a post by Jeffery Palermo on how to get around branched code and dependency injection http://jeffreypalermo.com/blog/constructor-over-injection-anti-pattern/
In his post, Jeffery has a class (public class OrderProcessor : IOrderProcessor) that takes 2 interfaces on the constructor. One is a validator IOrderValidator and an IOrderShipper interface. His method code branches after only using methods on the IOrderValidator interface and never uses anything on the IOrderShipper interface.
He suggests creating a factory that will call a static method to get the delegate of the interface. He is creating a new object in his refactored code which seems unnecessary.
I guess the crux of the issue is we are using IoC to build all our objects regardless if they're being used or not. If you instantiate an object with 2 interfaces and have code that could branch to not use one of them, how do you handle it?
In this example, we assume _validator.Validate(order) always returns false and the IOrderShipper.Ship() method is never called.
Original Code:
public class OrderProcessor : IOrderProcessor
{
private readonly IOrderValidator _validator;
private readonly IOrderShipper _shipper;
public OrderProcessor(IOrderValidator validator, IOrderShipper shipper)
{
_validator = validator;
_shipper = shipper;
}
public SuccessResult Process(Order order)
{
bool isValid = _validator.Validate(order);
if (isValid)
{
_shipper.Ship(order);
}
return CreateStatus(isValid);
}
private SuccessResult CreateStatus(bool isValid)
{
return isValid ? SuccessResult.Success : SuccessResult.Failed;
}
}
public class OrderShipper : IOrderShipper
{
public OrderShipper()
{
Thread.Sleep(TimeSpan.FromMilliseconds(777));
}
public void Ship(Order order)
{
//ship the order
}
}
Refactored Code
public class OrderProcessor : IOrderProcessor
{
private readonly IOrderValidator _validator;
public OrderProcessor(IOrderValidator validator)
{
_validator = validator;
}
public SuccessResult Process(Order order)
{
bool isValid = _validator.Validate(order);
if (isValid)
{
IOrderShipper shipper = new OrderShipperFactory().GetDefault();
shipper.Ship(order);
}
return CreateStatus(isValid);
}
private SuccessResult CreateStatus(bool isValid)
{
return isValid ? SuccessResult.Success : SuccessResult.Failed;
}
}
public class OrderShipperFactory
{
public static Func<IOrderShipper> CreationClosure;
public IOrderShipper GetDefault()
{
return CreationClosure(); //executes closure
}
}
And here is the method that configures this factory at start-up time (global.asax for ASP.NET):
private static void ConfigureFactories()
{
OrderShipperFactory.CreationClosure =
() => ObjectFactory.GetInstance<IOrderShipper>();
}
I just posted a rebuttal of Jeffrey Palermos post.
In short, we should not let concrete implementation details influence our design. That would be violating the Liskov Substitution Principle on the architectural scale.
A more elegant solution lets us keep the design by introducing a Lazy-loading OrderShipper.
I'm running late for a meeting, but a few quick points...
Sticking to the code branching of using only one dependency, there are two branches to propose:
Applying DDD practices, you would not have an OrderProcessor with a dependency on IOrderValidator. Instead, you'd make the Order() entity be responsible for its own validation. Or, stick to your IOrderValidator, but have its dependency within the OrderShipper() that is implemented - since it will return any error codes.
Ensure the dependencies being injected are constructed using a Singleton approach (and configured as Singleton in the IoC container being used). This resolves any memory concerns.
Like someone else that mentioned here, the point is to break the dependency on concrete classes and loosely couple the dependencies using Dependency Injection with some IoC container in use.
This makes future refactoring and swapping out legacy code far easier on a grand scale by limiting the technical debt incurred in the future. Once you have a project near 500,000 lines of code, with 3000 unit tests, you'll know first hand why IoC is so important.
Related
Trying to use Command/Handler pattern and Aspect Oriented Programming with Simple Injector.
I have my command and handler classes.
ICommandHandler.cs
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
MakeCoffeeCommand.cs
public class MakeCoffeeCommand
{
public string Flavor { get; set; }
}
MakeCoffeeCommandHandler.cs
internal class MakeCoffeeCommandHandler : ICommandHandler<MakeCofeeCommand>
{
public void Handle(MakeCoffeeCommand command)
{
...
}
}
MakeCakeCommand.cs
public class MakeCakeCommand
{
public float OvenTemperature { get; set; }
}
MakeCakeCommandHandler.cs
internal class MakeCakeCommandHandler : ICommandHandler<MakeCakeCommand>
{
public void Handle(MakeCakeCommand command)
{
...
}
}
So far, I can inject implementation through this single rule.
//this rule automagically ignores possibly existing decorators! :-)
c.Register(typeof(ICommandHandler<>), typeof(ICommandHandler<>).Assembly);
Then, I would like to register decorators aimed at validating the command instance. My decorator implementations depend on the concrete command types. I created an interface all the decorators have to inherit from.
ICommandHandlerValidator.cs
public interface ICommandHandlerValidator<TCommand> : ICommandHandler<TCommand>
{
}
Then, the concrete decorators.
ValidatorMakeCoffeeCommandDecorator.cs
internal class ValidatorMakeCoffeeCommandDecorator
: ICommandHandlerValidator<MakeCoffeeCommand>
{
private readonly ICommandHandler<MakeCoffeeCommand> decoratee;
public ValidatorMakeCoffeeCommandDecorator(ICommandHandler<MakeCoffeeCommand> decoratee)
{
this.decoratee = decoratee;
}
public void Handle(MakeCoffeeCommand command)
{
...
}
}
ValidatorMakeCakeCommandDecorator.cs
internal class ValidatorMakeCakeCommandDecorator
: ICommandHandlerValidator<MakeCakeCommand>
{
private readonly ICommandHandler<MakeCakeCommand> decoratee;
public ValidatorMakeCakeCommandDecorator(ICommandHandler<MakeCakeCommand> decoratee)
{
this.decoratee = decoratee;
}
public void Handle(MakeCakeCommand command)
{
...
}
}
I'm trying to register these validators with a single line, as in the previous case.
c.RegisterDecorator(typeof(ICommandHandler<>), typeof(ICommandHandlerValidator<>));
But I get this error.
The given type ICommandHandlerValidator<TCommand> is not a concrete type. Please use one of the other overloads to register this type.
It this a correct approach?
If yes, how is it possible to get rid of the error?
Note: I have to implement multiple decorators for all cross-cutting concerns. Some of them depend on the concrete command (i.e. authorization, full-text indexing), some do not, and have the same implementation shared by all the commands (i.e. logging, performance analysis).
It this a correct approach?
This answer might be a bit opinionated, but to me, this isn't the right approach. Your ICommandHandlerValidator<T> interface serves no function, and your decorators can as easily derive directly from ICommandHandler<T>.
On top of that, you are somewhat 'abusing' decorators to implement very specific logic, while decorators are best suited to implement very generic cross-cutting concerns.
Although you might argue that validation is very generic, your implementations aren't generic at all, since each decorator has logic that is specific to a single handler implementation. This leads to the situation that you get many decorators, and need to batch-register them.
What I typically like to do is to take a step back and look at the design. In your architecture you determined that business logic that mutates state is a certain artifact that deserves its own abstraction. You call this abstraction ICommandHandler<T>. Not only does this allow you to clearly distinguish these particular type of components from other components in the system, it allows you to batch register them and apply cross-cutting concerns very effectively.
While looking at your code, however, it seems to me that logic that validates commands before they are executed by their command handler has importance of its own in your application. That means it deserves an abstraction of its own. For instance, you can call it ICommandValidator<T>:
public interface ICommandValidator<TCommand>
{
IEnumerable<ValidationResult> Validate(TCommand command);
}
Note that this interface has no relationship with ICommandHandler<TCommand>. Validation components are a different artifact. The ICommandValidator<T> interface returns validation results, which can be practical for implementations. You might want to play with the best design for this validator.
Using this interface you can now define specific validators:
public class MakeCoffeeValidator : ICommandValidator<MakeCoffeeCommand> { ... }
public class MakeCakeValidator : ICommandValidator<MakeCakeCommand> { ... }
Besides the visibility of these validators in your design, this separate interface allows your validators to be batch-registered:
c.Collection.Register(typeof(ICommandValidator<>),
typeof(MakeCakeValidator).Assembly);
Here, the validators are registered as collection, assuming that there might be zero or multiple validator implementations for a single command. If there is always exactly one implementation (as you'll see with command handler implementations), you should call c.Register instead.
This by itself, however, doesn't do much, because those validators will not get executed by themselves. For this you will need to write a generic piece of cross-cutting code that can be applied to all command handlers in the system. In other words, you need to write a decorator:
public class ValidatingCommandHandlerDecorator<T> : ICommandHandler<T>
{
private readonly ICommandHandler<T> decoratee;
private readonly IEnumerable<ICommandValidator<T>> validators;
public ValidatingCommandHandlerDecorator(
IEnumerable<ICommandValidator<T>> validators,
ICommandHandler<T> decoratee)
{
this.validators = validators;
this.decoratee = decoratee;
}
public void Handle(T command)
{
var validationResults = (
from validator in this.validators
from result in validator.Validate(command)
select result)
.ToArray();
if (validationResults.Any())
{
throw new ValidationException(validationResults);
}
this.decoratee.Handle(command);
}
}
This decorator can be registered in a way you are already familair with:
c.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(ValidatingCommandHandlerDecorator<>));
Although you could try to batch-register this decorator, together with all decorators in the system, that would typically not work out great. This is because the order in which you execute cross-cutting concerns is of vital importance. For instance, when you implement a deadlock retry decorator and a transaction decorator, you wish to have the deadlock decorator to wrap the transaction decorator, otherwise you might end up retrying a deadlocked operation outside the context of a transaction (because of the way SqlTransaction and SQL server work). Likewise, you wish to operate writing the audit trail inside a transaction. Otherwise you could end up missing an audit trail for a succeeded operation.
What is wrong with having the dependency object as a static field in a static class instead of injecting it to each object that depends on it through constructor?
public static class Dependencies
{
public static IUsersRepository Users;
...
}
//Use in a method that depends on Users Repository
var users = Dependencies.Users.GetUsers();
VS.
public class UserController
{
private IUsersRepository _users;
public UserController(IUsersRepository repo)
{
this._users = repo;
}
public List<User> GetCustomUsers()
{
var users = this._users.GetUsers();
...
}
}
There is a DI pattern called "Ambient Context" you can use to do this.
It allows you to avoid passing a cross-cutting concern all the time, but it still allows you to Unit Test things.
The canonical example is a DateTime provider:
public abstract class TimeProvider {
private static TimeProvider current =
DefaultTimeProvider.Instance;
public static TimeProvider Current {
get { return TimeProvider.current; }
set {
if (value == null) {
throw new ArgumentNullException("value");
}
TimeProvider.current = value;
}
}
public abstract DateTime UtcNow { get; }
public static void ResetToDefault() {
TimeProvider.current = DefaultTimeProvider.Instance;
}
}
Where an implementation might look like this:
public class DefaultTimeProvider : TimeProvider {
private readonly static DefaultTimeProvider instance =
new DefaultTimeProvider();
private DefaultTimeProvider() { }
public override DateTime UtcNow {
get { return DateTime.UtcNow; }
}
public static DefaultTimeProvider Instance {
get { return DefaultTimeProvider.instance; }
}
}
Code would use TimeProvider.Current to access the DateTime rather than using DateTime directly.
The default concrete implementation returns the usual DateTime.UtcNow. However, for unit testing you can use a special test implementation and set TimeProvider.Current to it before running the unit tests.
See this page (where that code comes from) for more information.
Note that you should only use this pattern for truly cross-cutting concerns such as DateTime, security, logging and so on.
Suppose that a UserController would like to use an instant IUsersRepository and another UserController would like to use an instance of a different IUserRepository implementation, then you can't do this with static dependencies.
To be honest, the police aren't going to come knocking on your door if you do, but taken to it's logical conclusion (i.e. an application of any appreciable size) you end up with a more difficult to maintain "spaghetti code" codebase.
Mostly, coupling, and things like the SOLID principles. You are tightly coupling to the Dependency class, when ideally DI prevents this by building object graphs for you, injecting the dependencies, so those objects have no knowledge (i.e. are not coupled) to the implementation that provides them. If you're using a DI container and a singleton lifestyle, then you've essentially got what you describe - static fields. But with a container (even the "containerless" style containers that are becoming popular) you get more flexibility and the hard things are done for you.
There are a few cases where using DI, particularly via a container, are probably a bad idea (logging, generating new Guid values, getting the current date). You can solve those few cases with the "ambient context" solution (see Matthew Watson's answer for more details).
I am new to TDD and I am using Moq as my mocking framework.
I am trying to check if a method has been called in my class.
The class is not implementing any Interface.
var mockFooSaverService = new Mock<FooSaverService>();
mockFooSaverService.Verify(service => service.Save(mockNewFoo.Object));
to make this work I found here that I have to make the Save() method as a Virtual method.
Question:
What are the consequences of using Virtual keyword for all methods in a class just for the sake of making it testable?
TL;DR
As per the comments, the need for the virtual keyword indicates that your class hierarchy is too tightly coupled, and you should apply SOLID principles to decouple them from eachother. This has the "happy" side effect of making your class hierarchy easier to Unit Test, as dependencies can be mocked via the interface abstraction.
In more Detail
The need make all public methods virtual to allow Moq to override them is frequently indicative of a separation of concerns or class coupling smell.
e.g. this scenario needed virtual methods because class under test has multiple concerns, and there was a need to mock one method and actually invoke another method in the same system under test.
As per #JonSkeet's comment, it is commonplace SOLID best practice to abstract dependencies as interfaces. As it stands, your class under test (May I call it "Controller"?) is dependent on the concrete FooSaverService to save Foos.
By applying the Dependency Inversion Principle, this coupling can be loosened, by abstracting just the externally useful methods, properties and events of FooSaverService to an interface (IFooSaverService), and then
FooSaverService implements IFooSaverService
Controller depends only on IFooSaverService
(Obviously, there are likely other optimizations, e.g. to make the IFooSaverService generic, e.g. ISaverService<Foo> but not in scope here)
Re : Mock<Foo> - it is fairly uncommon to need to Mock simple data storage classes (POCO's, Entities, DTO's etc) - since these will typically retain data stored in them and can be reasoned over directly in unit tests.
To answer your question re implications of Virtual (which is hopefully less relevant now):
You are breaking the (polymorphic) Open and Closed Principle - it is inviting others to override behaviour without deliberately designing for this - there may be unintended consequence.
As per Henk's comment, there will be a small performance impact in administering the virtual method table
A code example
If you put all this together, you'll wind up with a class hierarchy like so:
// Foo is assumed to be an entity / POCO
public class Foo
{
public string Name { get; set; }
public DateTime ExpiryDate { get; set; }
}
// Decouple the Saver Service dependency via an interface
public interface IFooSaverService
{
void Save(Foo aFoo);
}
// Implementation
public class FooSaverService : IFooSaverService
{
public void Save(Foo aFoo)
{
// Persist this via ORM, Web Service, or ADO etc etc.
}
// Other non public methods here are implementation detail and not relevant to consumers
}
// Class consuming the FooSaverService
public class FooController
{
private readonly IFooSaverService _fooSaverService;
// You'll typically use dependency injection here to provide the dependency
public FooController(IFooSaverService fooSaverService)
{
_fooSaverService = fooSaverService;
}
public void PersistTheFoo(Foo fooToBeSaved)
{
if (fooToBeSaved == null) throw new ArgumentNullException("fooToBeSaved");
if (fooToBeSaved.ExpiryDate.Year > 2015)
{
_fooSaverService.Save(fooToBeSaved);
}
}
}
And then you'll be able to test your class which has the IFooSaverService dependency as follows:
[TestFixture]
public class FooControllerTests
{
[Test]
public void PersistingNullFooMustThrow()
{
var systemUnderTest = new FooController(new Mock<IFooSaverService>().Object);
Assert.Throws<ArgumentNullException>(() => systemUnderTest.PersistTheFoo(null));
}
[Test]
public void EnsureOldFoosAreNotSaved()
{
var mockFooSaver = new Mock<IFooSaverService>();
var systemUnderTest = new FooController(mockFooSaver.Object);
systemUnderTest.PersistTheFoo(new Foo{Name = "Old Foo", ExpiryDate = new DateTime(1999,1,1)});
mockFooSaver.Verify(m => m.Save(It.IsAny<Foo>()), Times.Never);
}
[Test]
public void EnsureNewFoosAreSaved()
{
var mockFooSaver = new Mock<IFooSaverService>();
var systemUnderTest = new FooController(mockFooSaver.Object);
systemUnderTest.PersistTheFoo(new Foo { Name = "New Foo", ExpiryDate = new DateTime(2038, 1, 1) });
mockFooSaver.Verify(m => m.Save(It.IsAny<Foo>()), Times.Once);
}
}
TL;DR;
Another good answer is - making classes extendable, and providing virtual methods (i.e. the possibility to extend them) is "feature" of that class. And this feature needs to be supported and tested as any other feature.
Much better explanation can be read on Eric Lippert's blog.
I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)
Is this a valid example for decorator pattern?
I would like to know is this example a valid example for decorator pattern? if not what
is correction or change needed here, please suggest.
We have a Container class representing container and for it i want to add features at
run time. features like wheel and lid are used in the example.
Client code:
private void button2_Click(object sender, EventArgs e)
{
IContainer container = new MovableConatiner(new Container());
string features = container.getFeatures();
container = new LidConatiner(container);
features = container.getFeatures();
}
API code:
public interface IContainer
{
string getFeatures();
}
public class Container : IContainer
{
public string getFeatures()
{
return "Container";
}
}
// a decorator to add wheels
public class MovableConatiner : IContainer
{
protected IContainer container;
public MovableConatiner(IContainer container)
{
this.container = container;
}
public string getFeatures()
{
string features = container.getFeatures();
features = features != string.Empty ? string.Format("{0} , four wheels", features) :
features;
return features;
}
}
// a decorator to add lid to contaner
public class LidConatiner : IContainer
{
protected IContainer container;
public LidConatiner(IContainer container)
{
this.container = container;
}
public string getFeatures()
{
string features = container.getFeatures();
features = features != string.Empty ? string.Format("{0} , Lid", features) :
features;
return features;
}
}
its as per my understand so i would like to verify my understanding.
While your implementation doesn't ideally reflects the structure or the Decorator pattern, from my point of view it solves the same problem that Decorator is targeted to solve. Your solution is just not as strict and safe for future modifications as "ideal" Decorator implementation.
You simplified implementation removing "unnecessary" for you abstractions. But while you might think they are unnesessary at the moment, they will become very useful in the future when your application grows and get few dozens of components and decorators. it's easy to get lost who is who currently.
In the link I provided there is very simple description of main participants of the Decorator pattern, and there is a sample code, very similar to yourth, but complete. I won't copy-paste it here to show you corrent implementation.
I just want to stress that if you don't understand the need of some abstractions in Design patterns, you better leave them, or read once more how to use it instead of just removing them.
UPDATE: point in favour of abstractions:
All common logic must be implemented in one place and reused. Code duplication is very-very bad. I think everybody agrees that this is fundamental principle of well-organized code.
Now let's analyze your implementation of Decorator pattern without extracting abstract base class for decorators. Compare the implementation of your MovableContainer and LidContainer classes - do you see anything similar? I hardly see any difference at all actually. Ok, let's find what's common:
both have constructors, receiving component to decorate.
both store reference to IContainer which is decorated
both retrieve component's features in the getFeatures() method
both check component's features for empty and if not - append some string (the only difference is string itself)
All this logic should be extracted to base class. You already should udnerstand that base class for your two decorators is required.
Let's go further. Let's imagine every possible decorator for every possible container. As implies from the Decorator pattern definition, it's obvious that some logic is common for all decorators: they all store reference to the decorating object. Is that enough for extracting base class (single property - that's not hard to copy-paste it to both decorators you have)? Definitely enough!
If you like real-life examples, here it is. You've implemented few decorators, let's say 100 (2 is still enouth, 100 just exadurates the problem). And they you realize that some decelopers doesn't know how to use them properly - they just pass NULLs to your decorators. Their code works fine, then created decorators are passed somewhere else, or stored to DB etc. And then at some magical points, your code is failing in various places later. It's hard to every time find where that NULL came from, which part of application created such object. You decide to add NULL-check in the constructor to disallow passing NULLs and make initial code fail to immediately fix the problem. Ouch, we need to fix all 100 constructors! And merge your changes with changes of 10 more developers who are working everybody on his decorator. That's not a good perspective.
If this example didn't convince you and you are still ready to copy-paste code 100 times, imagine that you are developing a reusable library and other developers from other companies also implement decorators derived from your IContainer. You have no way to fix constructors of their decorators and ensure they won't provide you with invalid object containint NULL internally. On contrary if you had a base class for Decorator, you just needed to fix it - and all implementations both yourth and 3rd party get that functionality. If you think you don't implement a reusable library - consider other developers working in your team as 3rd party - it's always useful and not so different - don't require them to change their code because you need some fix.
Finally I provide the way I would refactor your code (I didn't want to do it at the beginning to let you come to this on your own):
public interface IContainer
{
string getFeatures();
}
public class Container : IContainer
{
public string getFeatures()
{
return "Container";
}
}
public abstract class ContainerDecorator : IContainer
{
protected IContainer container;
protected ContainerDecorator(IContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public abstract string getFeatures();
}
public class StringFormatDecorator : ContainerDecorator
{
private readonly string _format;
public StringFormatDecorator(IContainer container, string format) : base(container)
{
_format = format;
}
public override string getFeatures()
{
string features = container.getFeatures();
features = features != string.Empty ? string.Format(_format, features) : features;
return features;
}
}
// a decorator to add wheels
public class MovableConatiner : StringFormatDecorator
{
public MovableConatiner(IContainer container) : base(container, "{0} , four wheels")
{
}
}
// a decorator to add lid to contaner
public class LidConatiner : StringFormatDecorator
{
public LidConatiner(IContainer container) : base(container, "{0} , Lid")
{
}
}
Such code not only improves core reuse, but also prevents others from using your decorators in wrong way because of lost border between containers and decorators. It's much harder to declare parameterless decorator now and almost impossible to use it. You can't "decorate" one container with another container which is non-sense, but possible in your implementation when some new developer creates his own container without knowing your initial intentions.
Now doing things wrong becomes much more complex.