Trying Decorator Design Pattern, what's wrong with this code? - c#-4.0

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";
}
}

Related

Map to specific derived type based on value on source using Automapper

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.

How is IClock resolved with SystemClock in this example?

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>();

How do I access a derived class value from a base class static method?

Here is a sample of what I am trying to accomplish:
public class BaseClass<T>
{
public static T GetByID(int ID)
{
// Need database name here that is determined at design time in the derived class.
var databaseName = "";
// do some stuff involving database name that gets me object by ID here.
return default(T);
}
}
public class DerivedClass : BaseClass<DerivedClass>
{
private string DatabaseName { get; set; }
}
Basically, how would I access the derived "DatabaseName" in the base class static GetByID method?
EDIT: After I posted this, I tried one more thing. I played with attributes earlier, and failed, but I think my brain was mushy. Just tried again and ran a test, and it is working. Here is the updated sample.
public class BaseClass<T>
{
public static T GetByID(int ID)
{
// Need database name here that is determined at design time in the derived class.
var databaseName = ((DatabaseAttribute)typeof(T).GetCustomAttributes(typeof(DatabaseAttribute), true).First()).DatabaseName;
// do some stuff involving database name that gets me object by ID here.
return default(T);
}
}
[Database("MyDatabase")]
public class DerivedClass : BaseClass<DerivedClass>
{
}
public class DatabaseAttribute : Attribute
{
public DatabaseAttribute(string databaseName)
{
DatabaseName = databaseName;
}
public string DatabaseName { get; set; }
}
Base class to derived class is a one-way inheritance: The base class has no knowledge of the existance of a derived class, and so it can't access it.
In addition to that you will have a hard time accessing a non-static property from a static method.
I know you've already answered your own question, but some improvements....
Add a where clause to guarantee inheritance, it means any static methods can make use of inherited methods. You might also want to add the new() clause if you wish to be able to create instances of the inherited class.
public class BaseClass<T> : where T : BaseClass<T>
{
static readonly string databaseName;
static BaseClass() {
// Setup database name once per type of T by putting the initialization in
// the static constructor
databaseName = typeof(T).GetCustomAttributes(typeof(DatabaseAttribute),true)
.OfType<DatabaseAttribute>()
.Select(x => x.Name)
.FirstOrDefault();
}
public static T GetByID(int ID)
{
// Database name will be in the static field databaseName, which is unique
// to each type of T
// do some stuff involving database name that gets me object by ID here.
return default(T);
}
}
[Database("MyDatabase")]
public class DerivedClass : BaseClass<DerivedClass>
{
}
public class DatabaseAttribute : Attribute
{
public DatabaseAttribute(string databaseName)
{
DatabaseName = databaseName;
}
public string DatabaseName { get; set; }
}

Enum-Like object which contains properties

I am trying to figure out a way to have a class full of static objects which each can have a variety of static properties.
I want to be able to pass these properties around and even set them as static properties of other object and I also want to be able to switch through the objects.
Here is an example illustrating what I mean:
Creating and Sending a Message
class Program
{
static void Main(string[] args)
{
MarketOrder Order = new MarketOrder("DELL", MessageProperties.SecurityType.Equity, MessageProperties.ExchangeDestination.ARCA.PostOnly);
SendOrder(Order);
Console.ReadLine();
}
public static void SendOrder(MarketOrder Order)
{
switch (Order.SecurityType)
{
case MessageProperties.SecurityType.Equity:
// Equity sending logic here
break;
case MessageProperties.SecurityType.Option:
// Option sending logic here
break;
case MessageProperties.SecurityType.Future:
// Future sending logic here
break;
}
}
}
This does not want to compile because it won't let me switch the Order.SecurityType object.
MarketOrder Class
public class MarketOrder
{
public readonly string Symbol;
public readonly MessageProperties.SecurityType SecurityType;
public readonly MessageProperties.ExchangeDestination ExchangeDestination;
public MarketOrder(string Symbol, MessageProperties.SecurityType SecurityType, MessageProperties.ExchangeDestination ExchangeDestination)
{
this.Symbol = Symbol;
this.SecurityType = SecurityType;
this.ExchangeDestination = ExchangeDestination;
}
}
MessageProperties Class
public abstract class MessageProperties
{
public class ExchangeDestination
{
public readonly string Value;
public readonly double ExchangeFee;
public ExchangeDestination(string Value, double ExchangeFeed)
{
this.Value = Value;
this.ExchangeFee = ExchangeFee;
}
public abstract class ARCA
{
public static ExchangeDestination Only = new ExchangeDestination("ARCA.ONLY", 0.01);
public static ExchangeDestination PostOnly = new ExchangeDestination("ARCA.ONLYP", 0.02);
}
public abstract class NYSE
{
public static ExchangeDestination Only = new ExchangeDestination("NYSE.ONLY", 0.01);
public static ExchangeDestination PostOnly = new ExchangeDestination("NYSE.ONLYP", 0.03);
}
}
public class SecurityType
{
public readonly string Value;
public SecurityType(string Value)
{
this.Value = Value;
}
public static SecurityType Equity = new SecurityType("EQ");
public static SecurityType Option = new SecurityType("OPT");
public static SecurityType Future = new SecurityType("FUT");
}
}
Enums work perfectly for what I am trying to do except it is hard to have multiple properties of an enum value. I considered using Attributes on Enums to set the properties but getting those vs. getting static properties of objects is substantially slower and my application is extremely speed/latency sensitive.
Is there perhaps a better way of accomplishing what I am trying to do?
Thanks in advance for your help!
William

JAXB/MOXy: How to partially unmarshall, passing the descendants of a given node to a closed/proprietary class?

I'm starting with some Java classes that I would like to be able to unmarshall from XML--I'm determining the schema as I go. I would like to use XML similar to the following:
<Person fname="John" lname="Doe">
<bio><foo xmlns="http://proprietary.foo">Blah <bar>blah</bar> blah</foo></bio>
</Person>
I'm hoping to annontate my Java classes similar to the following:
public class Person {
#XmlAttribute
public String fname;
#XmlAttribute
public String lname;
#XmlElement
public ProprietaryFoo bio;
}
I'd like to pass the <foo xmlns="http://proprietary.foo"> element and it's descendants to a compiled factory class which works like this:
FooFactory.getFooFromDomNode(myFooElement) // Returns a private ProprietaryFooImpl as an instance of the public ProprietaryFoo Interface
It seems like I need to create a DomHandler for ProprietaryFoo but I'm not quite able to figure it out (I was getting “com.xyz.ProprietaryFooImpl nor any of its super class is known to this context.") I'm also interested in XmlJavaTypeAdapter I can't figure out how to receive the ValueType as an Element.
Ended up using both an XmlAdapter and a DomHandler along with a simple Wrapper class.
public class FooWrapper {
#XmlAnyElement(FooDomHandler.class)
public ProprietaryFoo foo;
}
public class FooXmlAdapter extends XmlAdapter<FooWrapper, ProprietaryFoo> {
#Override
public ProprietaryFoo unmarshal(FooWrapper w) throws Exception {
return w.foo;
}
#Override
public FooWrapper marshal(ProprietaryFoo f) throws Exception {
FooWrapper fooWrapper = new FooWrapper();
fooWrapper.foo = f;
return fooWrapper;
}
}
/* The vendor also provides a ProprietaryFooResult class that extends SAXResult */
public class FooDomHandler implements DomHandler<ProprietaryFoo, ProprietaryFooResult> {
#Override
public ProprietaryFooResult createUnmarshaller(ValidationEventHandler validationEventHandler) {
return new ProprietaryFooResult();
}
#Override
public ProprietaryFoo getElement(ProprietaryFooResult r) {
return r.getProprietaryFoo();
}
#Override
public Source marshal(ProprietaryFoo f, ValidationEventHandler validationEventHandler) {
return f.asSaxSource();
}
}
For whatever reason, this didn't work with the standard classes from the com.sun namespace but MOXy handles it well.

Resources