I have a design issue that I encounter currently.
Let's say there is a hierarchy of components. Each of these component derives from an abstract Component type which looks something like this:
public abstract class Component
{
public abstract Component Parent { get; }
public abstract ComponentCollection Children { get; }
}
Now I want to add some optional functionality to those components, lets take being able to search within the component hierarchy and to select components within the hierarchy as examples.
Is it considered bad practice to provide those optional functionality in the base class like this:
public abstract class Component
{
// Other members
public abstract bool IsSearchable { get; }
public abstract bool Search(string searchTerm);
public abstract bool IsSelectable { get; }
public abstract bool Select();
}
While the "search-ability" and "select-ability" is managed in derived components by e.g. using strategy patterns?
Somehow this seems like violation of the SRP to me, but in my opinion the only alternative would be to have an interface for each optional functionality and only implement it on components that support this functionality.
In my opinion this would have the drawback that I have to write code like this everytime I want to check if a component provides specific functionality:
public bool Search(Component component, string searchTerm)
{
ISearchable searchable = component as ISearchable;
if(searchable != null)
{
searchable.Search(searchTerm);
}
}
Which strategy would you choose or do you have any better ideas?
Thanks in advance!
A possible option:
If the searchability/selectability implementation is provided through the strategy pattern (dependency injection), as you say, then I think interfaces for ISearchable and ISelectable are a better idea.
You can derive your strategy object from these interfaces, and implement getters for them in your base-Component class - GetSearchable(), GetSelectable() - where the default implementation in Component returns null (or a no-op implementation of the interface if you dislike null).
Why don't you use decorator?
Component c = new Component ();
var selectableAndSearchableOne = new SelectableComponent (new SearchableComponent (c));
Ok another one: this time you also know the component's extension points. with a visitor-like pattern
public interface IHasExtensions
{
List<Extension> Extensions { get; }
void Extend (Extension ext);
}
public class Component : IHasExtensions
{
List<Extension> exts = new List<Extension> ();
public List<Extension> Extensions
{
get { return exts; }
}
public void Extend (Extension ext)
{
exts.Add (ext);
}
void Draw() { }
}
public abstract class Extension
{
readonly protected Component _Component;
public Extension(Component component)
{
_Component = component;
}
}
public class SearchExtension : Extension
{
public SearchExtension (Component component) : base (component)
{
}
}
public class SelectionExtension : Extension
{
public SelectionExtension (Component component) : base (component)
{
}
}
public class test_fly
{
void start ()
{
Component c = new Component ();
c.Extend (new SearchExtension (c));
c.Extend (new SelectionExtension (c));
var exts = c.Extensions; // I Know the extensions now
}
}
Related
I'm having trouble implementing Automapper conversion in a situation where the source is a class which should be mapped to one of two derived classes based on a value on the source.
Here's a simplification of my classes:
public class FooContainerDTO
{
public FooDTO Foo { get; set; }
}
public class FooDTO
{
public string Type { get; set; }
//some properties..
}
public class FooContainer
{
public FooBase Foo { get; set; }
}
public abastract class FooBase
{
//some properties..
}
public class FooDerived1 : FooBase
{
//some properties
}
public class FooDerived2 : FooBase
{
//some properties
}
I'm using non-static Automapper so I create a MapperConfiguration from several Profiles at boot and inject the IMapper instance into my DI-container.
I want Automapper to map FooDTO to FooDerived1 when its Type property is "der1" and to FooDerived2 when it is "der2".
I've seen examples on this using the static api, something like this:
Mapper.CreateMap<FooContainerDTO, FooContainer>();
//ForMember configurations etc.
Mapper.CreateMap<FooDTO, FooDerived1>();
//ForMember configurations etc.
Mapper.CreateMap<FooDTO, FooDerived2>();
//ForMember configurations etc.
Mapper.CreateMap<FooDTO, FooBase>()
.ConvertUsing(dto => dto.Type == "der1"
? (FooBase) Mapper.Map<FooDerived1>(dto)
: Mapper.Map<FooDerived2>(dto));
This would map the Foo property of FooContainer to the correct derived type of FooBase.
But how can I do this without the static API?
The IMapper instance is not yet created at the point of configuring the profile.
Is there a way to leverage the overload of ConvertUsing() which takes a Func< ResolutionContext,object >? Can the resolution context give me whatever IMapper is currently being used? I've been looking, but can't find anything usable.
One way to get access to the mapping engine is via your own TypeConverter
abstract class MyTypeConverter<TSource,TDestination> : ITypeConverter<TSource, TDestination>
{
protected ResolutionContext context;
public TDestination Convert(ResolutionContext context)
{
this.context = context;
return Convert((TSource)context.SourceValue);
}
public abstract TDestination Convert(TSource source);
}
You then create an actual implementation like:
class MyTypeMapper : MyTypeConverter<EnumType,EnumTypeView>
{
public override EnumTypeView Convert(EnumType source)
{
return context.Engine.Mapper.Map<EnumTypeID, EnumTypeView>(source.EnumBaseType);
}
}
Except instead of unwrapping an enum structure, you'd check the type and call Map with different types.
I am trying to learn IOC principle from this screencast
Inversion of Control from First Principles - Top Gear Style
I tried do as per screencast but i get an error while AutomaticFactory try create an object of AutoCue. AutoCue class has contructor which takes IClock and not SystemClock. But my question is , in screencast IClock is resolved with SystemClock while inside AutomaticFactory .But in my code , IClock does not get resolved . Am i missing something ?
class Program
{
static void Main(string[] args)
{
//var clarkson = new Clarkson(new AutoCue(new SystemClock()), new Megaphone());
//var clarkson = ClarksonFactory.SpawnOne();
var clarkson = (Clarkson)AutomaticFactory.GetOne(typeof(Clarkson));
clarkson.SaySomething();
Console.Read();
}
}
public class AutomaticFactory
{
public static object GetOne(Type type)
{
var constructor = type.GetConstructors().Single();
var parameters = constructor.GetParameters();
if (!parameters.Any()) return Activator.CreateInstance(type);
var args = new List<object>();
foreach(var parameter in parameters)
{
var arg = GetOne(parameter.ParameterType);
args.Add(arg);
}
var result = Activator.CreateInstance(type, args.ToArray());
return result;
}
}
public class Clarkson
{
private readonly AutoCue _autocue;
private readonly Megaphone _megaphone;
public Clarkson(AutoCue autocue,Megaphone megaphone)
{
_autocue = autocue;
_megaphone =megaphone;
}
public void SaySomething()
{
var message = _autocue.GetCue();
_megaphone.Shout(message);
}
}
public class Megaphone
{
public void Shout(string message)
{
Console.WriteLine(message);
}
}
public interface IClock
{
DateTime Now { get; }
}
public class SystemClock : IClock
{
public DateTime Now { get { return DateTime.Now; } }
}
public class AutoCue
{
private readonly IClock _clock;
public AutoCue(IClock clock)
{
_clock = clock;
}
public string GetCue()
{
DateTime now = _clock.Now;
if (now.DayOfWeek == DayOfWeek.Sunday)
{
return "Its a sunday!";
}
else
{
return "I have to work!";
}
}
}
What you basically implemented is a small IoC container that is able to auto-wire object graphs. But your implementation is only able to create object graphs of concrete objects. This makes your code violate the Dependency Inversion Principle.
What's missing from the implementation is some sort of Register method that tells your AutomaticFactory that when confronted with an abstraction, it should resolve the registered implementation. That could look as follows:
private static readonly Dictionary<Type, Type> registrations =
new Dictionary<Type, Type>();
public static void Register<TService, TImplementation>()
where TImplementation : class, TService
where TService : class
{
registrations.Add(typeof(TService), typeof(TImplementation));
}
No you will have to do an adjustment to the GetOne method as well. You can add the following code at the start of the GetOne method:
if (registrations.ContainsKey(type))
{
type = registrations[type];
}
That will ensure that if the supplied type is registered in the AutomaticFactory as TService, the mapped TImplementation will be used and the factory will continue using this implementation as the type to build up.
This does mean however that you now have to explicitly register the mapping between IClock and SystemClock (which is a quite natural thing to do if you're working with an IoC container). You must make this mapping before the first instance is resolved from the AutomaticFactory. So you should add the following line to to the beginning of the Main method:
AutomaticFactory.Register<IClock, SystemClock>();
I have this code that explains the decorator pattern:
public abstract class IBeverage {
protected string description = "Unknown beverage";
public virtual string getDescription() {
return description;
}
}
public abstract class CondimentDecorator : IBeverage {
public abstract string getDescription();
}
public class Espresso : IBeverage {
public Espresso() {
description = "Espresso";
}
}
public class Mocha : CondimentDecorator {
IBeverage beverage;
public Mocha(IBeverage beverage) {
this.beverage = beverage;
}
public override string getDescription() {
return beverage.getDescription() + ", Mocha";
}
}
I should use it like:
static void Main(string[] args) {
IBeverage b = new Espresso();
Console.WriteLine(b.getDescription());
b = new Mocha(b);
Console.WriteLine(b.getDescription());
Console.ReadKey();
}
When I create the beverage (Beverage b = new Espresso();) _description is updated to "Espresso", when I decorate b with Mocha (b = new Mocha(b)), then _description takes the original value "Unknown Beverage". It should be "Espresso, Mocha". What's wrong?
This code was originally written in Java (the book was written with Java), but I translated it into C#. I guess Java works a little different from C#.
Because GetDescription() is not virtual.
public virtual string GetDescription() { ... }
virtual is the companion keyword to override, it's what allows subclasses to override methods. This is a key difference in C# from Java. In Java all methods are implicitly virtual.
You've actually got a few issues here (perhaps differing designs from Java). Even after sorting all of the naming issues, you will not get what you expect.
public abstract class CondimentDecorator : IBeverage {
public abstract string GetDescription();
}
The CondimentDecorator class will actually hide the IBeverage version GetDescription() method (you technically should use public new abstract string GetDescription();.
You are classifying the Mocha class as an IBeverage by assigning it to the b variable (which you earlier defined as an IBeverage via IBeverage b = new Espresso(), the IBeverage version of the GetDescription() method is what actually fires (totally ignoring the Mocha override of the CondimentDecorator GetDescription() method)
You can see this if you step through the code. Try using
CondimentDecorator m = new Mocha(b);
Console.WriteLine(m.GetDescription());
and you will get what you expect.
However, this kind of defeats the purpose of using a decorator in my opinion. A better option would be to change the design a bit and get rid of the CondimentDecorator. It is not providing anything other than confusion and unexpected behaviour. Instead try this:
This is your only needed abstract Beverage class:
public abstract class Beverage
{
// c# convention is to use properties instead of public fields.
// In this case I've used a private readonly backing field.
private readonly string _description = "Unknown Beverage";
protected string Description
{
get { return _description; }
set { _description = value; }
}
// Make this method virtual so you can override it, but if you
// choose not to, this is the default behaviour.
public virtual string GetDescription()
{
return Description;
}
}
This is a standard beverage class (can be decorated):
public class Espresso : Beverage
{
public Espresso()
{
// Setting the Beverage class Description property.
// You can use base.Description if you prefer to be explicit
Description = "Espresso";
}
}
This is a Beverage class that decorates another Beverage class:
public class Mocha : Beverage
{
// store an instance of the Beverage class to be decorated
private readonly Beverage _beverage;
// Beverage instance to be decorated is passed in via constructor
public Mocha(Beverage beverage)
{
_beverage = beverage;
}
// Override Beverage.GetDescription
public override string GetDescription()
{
// Calls decorated Beverage's GetDescription and appends to it.
return _beverage.GetDescription() + ", Mocha";
}
}
And now to get the behaviour you expect, you can run the same code as above:
static void Main(string[] args)
{
Beverage b = new Espresso();
Console.WriteLine(b.getDescription()); // "Espresso"
b = new Mocha(b);
Console.WriteLine(b.getDescription()); // "Espresso, Mocha"
Console.ReadKey();
}
As a side note. You can avoid using Console.ReadKey(); when debugging by using Ctrl + F5 This will automatically put in "Press any key to continue..." for you.
UPDATE
Since you want to include the CondimentDecorator class (as mentioned in your comment), you can create the following class:
public abstract class CondimentDecorator : Beverage
{
private readonly Beverage _beverage;
protected Beverage Bevy
{
get { return _beverage; }
}
protected CondimentDecorator(Beverage beverage)
{
_beverage = beverage;
}
}
Then you would change your Mocha class to the following:
// override CondimentDecorator instead of Beverage
public class Mocha : CondimentDecorator
{
// Pass the Beverage to be decorated to the base constructor
// (CondimentDecorator)
public Mocha(Beverage beverage)
: base(beverage)
{
// nothing needed in this constructor
}
public override string GetDescription()
{
// Now access the CondimentDecorator's Beverage property
// (which I called Bevy to differentiate it)
return Bevy.GetDescription() + ", Mocha";
}
}
When implementing custom filters I am currently using a pattern where my DTOs get both tagged with the filter attribute and also implement a custom interface that exposes some common variables I want to use in my services, for example:
public interface IMyInterface
{
Int32 MyVariable { get; set; }
}
[MyFilter]
public class MyDto
: IMyInterface
{
public Int32 MyVariable { get; set; }
}
public class MyFilterAttribute
: Attribute
, IHasRequestFilter
{
public int Priority { get { return 0; } }
public IHasRequestFilter Copy () { return this; }
public void RequestFilter(IHttpRequest req, IHttpResponse res, object requestDto)
{
var temp = requestDto as IMyInterface;
if( temp != null )
{
var x = [something from the request object...]
temp.MyVariable = x;
}
}
}
Is this the intended pattern? Or is there a way to do it solely with the interface? Is there a way to register a filter for all dtos that implement an inteface via the AppHost?
Unless you have a good reason to the recommendation is to inherit from RequestFilterAttribute which is specifically meant for this purpose which also lets you ignore providing default implementations for Priority and Copy().
If you do want to stick to IHasRequestFilter then the correct implementation for Copy() is:
public virtual IHasRequestFilter Copy()
{
return (IHasRequestFilter)this.MemberwiseClone();
}
This ensures that only a Copy is used per request and not the same instance, important to ensure ThreadSafety for when your filters maintaining state.
I'm looking to abstract a helper method. The method needs to be able to take in an object, do things with it depending on the type of object, and return a value. Would it be better to do something like this:
interface ICanDo
{
string DoSomething();
}
string DoThings(ICanDo mything)
{
return mything.DoSomething();
}
Or is it better to do something like this:
interface IStrategy
{
string DoSomething(object o);
}
string DoThings(object mything, IStrategy strategy)
{
return strategy.DoSomething(mything);
}
Is the latter even using a strategy pattern, since the strategy isn't being built into the class?
Is there a better way to do this I'm not thinking of? Would it be better to build the strategy into the class, using a wrapper for any class that needs to have DoThings run on it?
Sorry--I'm new to this pattern and trying to figure out where and how to use it best.
This is what I ended up putting together. I'm unsure if this follows good development principles.
class IndexWrapper
{
public interface IDocumentable
{
Document BuildDocument();
}
public interface IDocumentBuilder
{
Type SupportedType { get; }
Document BuildDocument(object o);
}
public class StringDocumentBuilder : IDocumentBuilder
{
public Type SupportedType { get { return typeof(string); } }
public Document BuildDocument(object o)
{
Document doc = new Document();
doc.Add(new Field("string", o as string, Field.Store.YES, Field.Index.ANALYZED));
return doc;
}
}
public static class IndexableFactory
{
public static IDocumentable GetIndexableObject(object o)
{
return GetIndexableObject(o, DocumentBuilderFactory.GetBuilder(o));
}
public static IDocumentable GetIndexableObject(object o, IDocumentBuilder builder)
{
return new IndexableObject(o, builder);
}
}
public static class DocumentBuilderFactory
{
private static List<IDocumentBuilder> _builders = new List<IDocumentBuilder>();
public static IDocumentBuilder GetBuilder(object o)
{
if (_builders.Count == 0)
{
_builders = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(type => typeof(IDocumentBuilder).IsAssignableFrom(type) && type.IsClass)
.Select(type => Activator.CreateInstance(type))
.Cast<IDocumentBuilder>()
.ToList();
}
return _builders.Where(builder => builder.SupportedType.IsAssignableFrom(o.GetType())).FirstOrDefault();
}
}
private class IndexableObject : IDocumentable
{
object _o;
IDocumentBuilder _builder;
public IndexableObject(object o) : this(o, DocumentBuilderFactory.GetBuilder(o)) { }
public IndexableObject(object o, IDocumentBuilder builder)
{
_o = o;
_builder = builder;
}
virtual public Document BuildDocument()
{
return _builder.BuildDocument(_o);
}
}
}
When in doubt, keep the KISS mantra in your mind - Keep It Short and Simple. Patterns can be very useful, but often they're only useful in specific cases and add unnecessary complexity otherwise.
In my experience, the strategy pattern is useful for when you have multiple different backends to choose from for a class. For example, say you have a logging class that your program uses to print debug information. Maybe in some cases, you want to log to a file. Maybe you'd like to log to a console. Perhaps you'd even like to log to a remote server with a proprietary protocol you company made!
So, your logging class may look like this:
interface IOutputWriter
{
void WriteLn(string message);
}
class ConsoleWriter : IOutputWriter
{
public ConsoleWriter()
{
}
public void WriteLn(string message)
{
Console.WriteLine(message);
}
}
class NetworkWriter : IOutputWriter
{
public NetworkWriter()
{
}
public void WriteLn(string message)
{
//Crazy propietary server protocol action
}
}
class Logger
{
IOutputWriter writer;
public Logger(IOutputWriter writer)
{
this.writer = writer;
}
public void Log(string message)
{
writer.WriteLn(message + "Date");
}
}
With the end result that your program code looks like this:
class Program
{
static void Main(string[] args)
{
Logger logger = new Logger(new ConsoleWriter());
logger.Log("Test");
}
}
The benefit is that if you want to use your crazy networking protocol, you can do it without even looking at the logging class. You just have to make a new class with your IOutputWriter interface and tell your logger to use your custom backend. The strategy pattern is essentially defining reusable interfaces and then using those interfaces to decouple algorithms from each other.