Multiple Decorators in Decorator Pattern - c#

I have read a few tutorials on the topic of the Decorator Pattern similar to this one. The basic example is a cake as in this tutorial, or a pizza as in other tutorials, and the decorators usually pass through values and modify them on the way (as in, every PizzaDecorator adds a small amount onto the price, thus returning the price of the pizza + all decorators). Now, that's certainly a nice example, but I am having a little trouble applying this to a less edible problem.
Suppose I have a base class that takes an input, according to which it modifies its state. Some of these state modifications cause an event to be raised which passes a value that could be considered the output. Now suppose the following features I'd like to individually add as decorators:
A buffer for the output
A history of the input
Another type of input (e.g. interprets a set of characters as allowed byte input values)
Individually, they are not so much of a problem. The basic functionality of the class (i.e. the TakeInput(byte input) and event Handler OutputAvailable) reside in an interface that the base class as well as the decorators can inherit (do I really need the extra abstraction layer as in the given example, i.e. a separate interface for the Decorator classes which in turn inherits from the base interface?). Now, if I implement the input cache in a decorator, how do I add it in such a way, that the next decorator would not hide it again? If I added, say, a list to simply store the input and made it available via a property, that property would be hidden should I decide that I also want the output buffered. I could keep references to both decorators around- but that would be rather messy, or so I think, because I am going to need quite a bunch of decorators. If I derived from the Decorator, the inheritance mess that I initially wanted to avoid by applying this pattern would not go away. How do I solve this problem?
As requested, a piece of code that illustrates my problem. (Or so I hope, anyway)
public interface ISampleClass
{
event OutputHandler OutputAvailable;
void TakeInput(byte input);
}
public class BaseSampleClass : ISampleClass
{
public event OutputHandler OutputAvailable;
void TakeInput(byte input)
{ // To keep things simple:
this.OutputAvailable(input);
}
}
public class SampleClassInputCacheDecorator : ISampleClass
{
private ISampleClass decoratedClass;
private List<byte> inputCache;
public event OutputHandler OutputAvailable;
public SampleClassInputCacheDecorator(ISampleClass decoratedClass)
{
this.decoratedClass = decoratedClass;
this.decoratedClass.OutputAvailable += (output) => {
this.OutputAvailable(output);
};
}
public List<byte> InputHistory { get { return this.inputCache; } }
public void TakeInput(byte input)
{
this.decoratedClass.TakeInput(input);
}
}
public class SampleClassCharInputAdapterDecorator : ISampleClass
{
private ISampleClass decoratedClass;
public SampleClassCharInputAdapterDecorator(ISampleClass decoratedClass)
{
this.decoratedClass = decoratedClass;
this.decoratedClass.OutputAvailable += (output) => {
this.OutputAvailable(output);
};
}
public void TakeInput(byte input)
{
this.decoratedClass.TakeInput(input);
}
public void TakeInput(char input)
{
switch (input)
{
case 'a':
this.TakeInput(27);
break;
case 'b':
// You get the idea...
}
}
}
// Now, I want to use the base class and get the benefit of both decorators:
ISampleClass smpl = new BaseSampleClass();
smpl = new SampleClassInputCacheDecorator(smpl);
smpl = new SampleClassCharInputAdapterDecorator(smpl);
// Dang, the input gets cached, but I can't access the InputHistory property.

Decorator is about altering the contracted behavior. You decorator adds completely new behavior, irrelevant in the context of the first one, and not being the part of the contract (the interface).
In fact SampleClassInputCacheDecorator is not a decorator - its actions are completely irrelevant from the ISampleClass point of view, as they don't influence TakeInput and OutputAvailable at all. It just depends on the ISampleClass chain, but does not "decorate" it. Proxy pattern seems more suitable here.

Related

A better architecture then if(something) DoIt() else Dont()

I'm trying to create a mechanism that will allow the application to decide (in runtime) whether to execute some functionality.
"Some Functionality" can be anything, it can be c# code which is contained in several classes in several dlls, it can be UI, it can be database query execution, etc.
Most importantly, it should fit in the current existing infrastructure I have, which I cannot re-design and build from scratch.
The more I think of it, it seems like the only solution I can use would be to hold some table which will be the "functionality repository" and it will tell (by unique key) if a functionality is on / off.
Then in code, I will have to place in each spot which handles such functionality an if else statement.
E.g.
If(functionalityEnabled)?
DoFunctionality()
Else
DoTheUsusal()
Is there a better way or a better design to implement it? I would like to keep the solution as simple as possible, but on the other hand, this solution is really ugly and will eventually make my code looks like spaghetti code.
Your thoughts will be appreciated,
I'm using c# with sql server, web api for web services.
Edit:
I want to say that I appreciate the time and effort of everyone answering my question, there were some really interesting ideas that you brought up.
I eventually marked #dasblinkenlight answer since it suited by need the best, though other answers here are really good and may be useful to others.
Thank you.
If you have two classes that implement the same interface, your application can call the functionality (methods, properties) of the class without knowing exactly if it is calling the basic functionality or the alternative functionality:
IFunctionalityX {
DoIt();
}
class BasicFunctionalityX: IFunctionalityX {
public DoIt() {
// Default behaviour goes here
}
}
class PluginFunctionalityX: IFunctionalityX {
public DoIt() {
// Alternative functionality.
}
}
If PluginFunctionalityX shares parts of its implementation with BasicFunctionalityX, you may inherit it from the other, but whether you do or not doesn't really matter. As long as you use the interface, that is what counts, and you can use this method regardless of whether the classes are related or not.
In the initialization of your program, you can make the decision once and create an instance of the right class. You may store this class in some container that holds all your functionalities. FunctionalityX is a property of interface IFunctionalityX, and you can make other interfaces (and properties) for other functionalities.
if (functionalityXEnabled) {
FunctionalityContainer.FunctionalityX = new PluginFunctionality();
} else {
FunctionalityContainer.FunctionalityX = new BasicFunctionality();
}
Then, in the rest of your application, you can call your functionality through:
FunctionalityContainer.FunctionalityX.DoIt();
Instead of implementing this from scratch you may use a dependancy injection library, like Unity. This also allows you to more easily get an instance of the right functionality at the time you need it without having to create them all at the start of your program, and without writing elaborate constructor code for all fucntionalities.
You want to dispatch your code differently at runtime dependent on a configuration setting. Conditionals and polymorphism are two ways of doing so.
Conditionals
At runtime, check for values using if, switch or other lookup methods. You're already doing these.
if (configFile.cloudAccount == null) {
saveFileToDisk();
} else saveFileToCloud();
Advantages
They're conditionals, you really can't avoid having to do one at some point in any nontrivial development project
Disadvantages
Doing them at every point in your application would be painful, though. So they're best combined with other strategies to minimise their use
Polymorphism
When loading your application, read through the configuration file and construct your application's components accordingly:
interface IFileSaver { /* Used to save files in your application */ }
class DiskSaver : IFileSaver { /* The default file saving class */ }
class CloudSaver : IFileSaver { /* If they've configured a cloud account */ }
// EXAMPLE USE
int Main (...) {
// Setup your application, load a config file.
// You'll need to check the config with a conditional
// here (uh oh) but other components of your application
// will just use the IFileSaver interface
if (configFile.cloudAccount != null) {
YourApplication.FileSaver = new CloudSaver(configFile.cloudAccount);
} else {
YourApplication.FileSaver = new DiskSaver();
}
}
// Somewhere else in your application
void SaveCurrentDocument() {
// No if's needed, it was front loaded when initialising
// the application
YourApplication.FileSaver.Save();
}
Advantages
Fits in nicely with object-oriented design
All your configuration checks are front loaded. After loading in the correct classes the rest of your program will use them, oblivious to their actual implementation. Because of that, you don't need to do if checks throughout your code.
Compiler will be able to statically check type errors in your approach
Disadvantages
Only as flexible as your class's interface. Maybe you want some extra steps and checks to occur with a CloudSaver, they'd better fit into the pre-existing interface; otherwise, they won't happen.
Long story short - conditionals let you explicitly perform the checks whenever they're needed so, in principle, you get a lot of procedural flexibility. For example, maybe the SaveAs routine needs to save files slightly differently than the Save routine. However, as you've identified, this leads to long repetitive code. In those cases, structuring your code to use polymorphism might help out.
Either way, you will almost certainly need to have some amount of conditional checks wherever there is flexibility in your application.
Note: There are many other ways of achieving runtime config checks, I'm just pointing out the most common (and usually straightforward)
A once-popular quip among OO programmers has been that every conditional in the code indicate a missed opportunity to subclass. Although this rule is far from being universal, and it falls short when it comes to composition, there is a grain of truth to it, especially when you see the same condition popping up in multiple ifs across different methods of the same class.
A common way of dealing with ifs like that is using some combination of inheritance and composition, and moving the decision to a single place where your object is being created.
The inheritance way looks like this:
interface Doer {
void doSomething();
}
class BasicDoer implements Doer {
public void doSomething() {
...
}
}
class EnhancedDoer extends BasicDoer {
public void doSomething() {
base.doSomething();
...
}
}
// At construction time:
Doer doer;
if (someCondition)
doer = new BasicDoer();
else
doer = new EnhancedDoer();
The composition way looks like this:
interface Doer {
void doSomething();
}
// Create several implementations of Activity, then...
// At construction time:
List<Doer> doers = new ArrayList<>();
if (someCondition1)
doers.add(new SomeKindOfDoer());
if (someCondition2)
doers.add(new AnotherKindOfDoer());
if (someCondition3)
doers.add(new YetAnotherKindOfDoer());
Now instead of an if you do this:
for (Doer d : doers) {
d.doSomething();
}
If it's just a single condition then you have no choice but to use if else and is perfect for single conditions.
If you have more then 1 condition, you may think of using Switch statement.
As far as you are worried about your code going to look complicated with if else statement, put your code within functions,
if(condition)
{
DoThis();
}
else
{
DoSomethingElse();
}
Maybe something similar to strategy design pattern (incapsulation of behaviour) will make it more managable if functionality doesn't require lots of interaction with object data (though interaction is possible). Pros: readable extendable code, cons: lots of code.
namespace SomethingLikeStrategy
{
public interface Behaviour {
void doThis();
void changeM(ref int m);
void doThat();
}
public class BehaviourOriginal : Behaviour {
public void doThis() {
Console.WriteLine("foo");
}
public void changeM(ref int m) {
m = 20;
}
public void doThat() {
throw new Exception("not implemented");
}
}
public class BehaviourSpecial : Behaviour {
public void doThis() {
Console.WriteLine("bar");
}
public void changeM(ref int m) {
m = 10;
}
public void doThat() {
throw new Exception("not implemented");
}
}
public class MyClass {
Behaviour mBehaviour;
int mM = 0;
public MyClass() {
mBehaviour = new BehaviourOriginal();
}
public void setSpecialBehaviour(bool special) {
if (special) {
mBehaviour = new BehaviourSpecial();
} else {
mBehaviour = new BehaviourOriginal();
}
}
public void doThis() {
mBehaviour.doThis();
}
public void doThat() {
mBehaviour.doThat();
}
public void changeM() {
mBehaviour.changeM(ref mM);
}
public void printM() {
Console.WriteLine(mM);
}
}
class Program
{
public static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.doThis();
myClass.setSpecialBehaviour(true);
myClass.doThis();
myClass.setSpecialBehaviour(false);
myClass.printM();
myClass.changeM();
myClass.printM();
myClass.setSpecialBehaviour(true);
myClass.changeM();
myClass.printM();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}

SOLID and C# events

I'm currently learning the SOLID (OO Design) and something bugs me: the dependency inversion principle, according to which the upper policy layer should be able to comply with a lower one's interface, made me wonder; where do event's fit in?
For example (taken from "Agile Principles, Patterns, and Practices in C#"):
Here, when the button is turned on/off, it calls turnOn/turnOff on the ButtonServer it would have some reference to.
Now if several objects were to depend on one single button, in order for this to work (imo), the button would have to store a list of ButtonServer's and then call on each one's turnOn/turnOff.
This looks to me like reinventing what event already does.
Now if that button were to have a new state, sleep, we'd have to create a new interface ButtonServerSleep (or some other name) and we'd have to store a new different list of each ButtonServerSleep which would be depending on the button*. And will just end up writing the same kind of code for looping through ButtonServer and call turnOn/turnOff than for looping through ButtonServerSleep and call sleep, the kind of code to which event's were made to avoid.
* if this would break the SRP, tell me.
The example with buttons and lamps is quite hard to follow, but I'll try:
public class Button
{
IButtonServer _buttonServer;
private bool _amIOn;
public Button(IButtonServer buttonServer)
{
_buttonServer = buttonServer;
}
void Poll()
{
_amIOn = !_amIOn;
if(_amIOn) _buttonServer.TurnOn(); else _buttonServer.TurnOff();
}
}
interface ITurnOnOffableDevice
{
void TurnOn();
void TurnOff();
}
interface IButtonServer : ITurnOnOffableDevice
{
void RegisterDevice(ITurnOnOffableDevice l);
}
public Lamp : ITurnOffableDevice
{
public Lamp(IButtonServer buttonServer)
{
buttonServer.RegisterDevice(this);
}
public void TurnOn()
{
Shine();
}
public void TurnOff()
{
Darken();
}
}
public MeatTriturator : ITurnOffableDevice
{
public MeatTriturator(IButtonServer buttonServer)
{
buttonServer.RegisterDevice(this);
}
public void TurnOn()
{
Triturate();
}
public void TurnOff()
{
ShutItDown();
}
}
Now, on some DLL which doesn't know about lamps, or meat triturators, you have this:
public ButtonServer : IButtonServer
{
private List<ITurnOnOffableDevice> _devices = new List<ITurnOnOffAbleDevice>();
public void RegisterDevice(ITurnOnOffAbleDevice l)
{
_devices.Add(l);
}
public void TurnOn()
{
foreach(var l in _devices) { l.TurnOn(); }
}
public void TurnOff()
{
foreach(var l in _devices) { l.TurnOff(); }
}
}
Then you create everything:
public static IButtonServer MyLampAndTrituratorButtonServer;
static void Prepare()
{
DependencyInject.ForType<IButtonServer>.Create<ButtonServer>();
}
static void Main()
{
Prepare();
MyLampAndTrituratorButtonServer = DependencyInject.CreateObject<IButtonServer>();
// The MyLampAndTrituratorButtonServer could be injected directly in the
// constructor of these objects, but for clarity I've left the normal
// object declaration
// this button will turn on lamps and meat triturators
var button = new Button(MyLampAndTrituratorButtonServer);
// these lamp and meat tritutator will be turned on/off by
// the buttons in that server
var lamp = new Lamp(MyLampAndTrituratorButtonServer);
var meatTriturator = new MeatTriturator(MyLampAndTrituratorButtonServer);
}
Then somewhere else, deep inside your program, you have the need to create a new button that lights up that lamp and meat triturator, you'd just do:
var button = new Button(MyLampAndTrituratorButtonServer);
No reference whatsoever to the actual lamp, or the meat triturator.
(Or better yet: create the button while injecting the IButtonServer dependency on the constructor parameter (this would depend on your dependency injector, so I'm not giving code), but then you'd neither need the reference to MyLampAndTrituratorButtonServer)
With this, you have decoupled your buttons from your lamps or meat triturators. The action of turning off and on is done by the button server, which as you can
see is injected, so it could be anything (anything that implements IButtonServer).
So you have delegated the responsibility of turning on and off the devices to a single dependency.
Again, in the "real world", buttons tend to do just one thing, and lamps only turn off and on, and this is dubious to change in the future... but this is an example of delegating the responsibility to a single point.
But let's take it a bit further... imagine your requirements have changed, and the buttons which turn on/off lamps and meat triturators (and only those, not all buttons), need to have a security measure. Whenever they are turned on, they need to auto-shutdown in 30 seconds.
With your "events based approach", you would need to derive one object from "button" (i.e., ButtonThatTurnsOffAt30secs : Button) and change -everywhere- where a lamp or meat triturator is created, then recompile.
With the isolated dependency, you'd just rewrite your buttonserver:
public ButtonServerThatTurnsOffAt30seconds : IButtonServer
{
private List<ITurnOnOffableDevice> _devices = new List<ITurnOnOffAbleDevice>();
public void RegisterDevice(ITurnOnOffAbleDevice l)
{
_devices.Add(l);
}
public void TurnOn()
{
foreach(var l in _devices) { l.TurnOn(); new Timer(30, () => { TurnOff(); } }
}
public void TurnOff()
{
foreach(var l in _devices) { l.TurnOff(); }
}
}
And change your dependency injection:
DependencyInject.ForType<IButtonServer>.Create<ButtonServerThatTurnsOffAt30seconds>();
If you have separated your project right, you wouldn't even need to recompile the whole application, just a single DLL change (or two if you have the dependency injector bootstrap on a different one) and voilá, now all your lamps and meat triturators turn off at 30 seconds.
Again, this is not the best example, and it made making an example hard, but I hope you can follow.
As a disclaimer: I'm trying to make a value on dependency isolation, not aiming to explain SOLID principles or any pattern, since you seem confused on that. I myself don't "follow patterns blindly", I just find whatever I find interesting on all those patterns and use it for a good purpose.
If you are sure your buttons will never change (or ALL your buttons will change at the same time), then there's no need for all of these. Whether going full-throttle on this, or whether to apply the GTD (Getting Things Done) principle, is up to you.
Applying patterns, decoupling dependencies, etc., takes time and effort, and depending on the project, deadline, budget, and possibility of it changing in the future, they are worth implementing or not.

Proper design of class hierarchy

I'm trying to design a class hierarchy in C# to properly model my application model.
The problem is I'm not sure which is the right way to do it.
Let's say I have an Order class which is supposed to be the base (abstract) class for all order types and the reference type I'm working with when using orders. The order class has only a single 'important' method: let's call it order.PlaceOrder(), but there are multiple (orthogonal) requirements that an order might have to do (or not do): log the placing of the order, place the order asynchronously (PlaceOrder method returns immediately) and others.
Now, I want to make actual concrete classes which can support any number of these requirements. For example:
class GoogleOrder : LoggedOrder, AsyncOrder, etc
class AppleOrder: AsyncOrder
class MicrosoftOrder : Order
The question is: if I want to create such a class by deriving from all the "strategies", then they all (but one) have to be interfaces, whereas I wish to inherit actual implementation and avoid copy/pasting of code, and I'm not sure how to do it.
I come from a C++ background, where I could just derive from multiple base classes (or possibly use a policy based design, like Andrei Alexandrescu describes in his book), but in C# I'm not sure how to do it, even though this seems like a very general question, one which I should know by now.
Any help is greatly appreciated!
It seems like your design calls for "Decorator pattern", Decorator pattern gives flexibility to add responsibilities/roles dynamically and with different combinations however you like instead of using inheritance.
here are example on how to implement decorator:
http://alagesann.com/2013/08/16/decorator-pattern-made-easy/
http://en.wikipedia.org/wiki/Decorator_pattern
hope that helps.
here is the sample code for your scenario. see if it helps.
public abstract class Order
{
public abstract void PlaceOrder(); // log the placeing of the ordr, place the order asynchronously
}
public class MicrosoftOrder : Order // default order
{
public void PlaceOrder()
{
// default implementation for placing order.
}
}
public class AppleOrder : Order // for asycn functionalities.
{
private Order order;
public AppleOrder(Order order)
{
this.order = order;
}
public void PlaceOrder()
{
// Implement async functionalities.
// you can also call default order as
// order.PlaceOrder();
}
}
public class GoogleOrder : Order // logged order
{
private Order order;
public GoogleOrder(Order order)
{
this.order = order;
}
public void PlaceOrder()
{
// Implement logged order
// you can also call default order as
// order.PlaceOrder();
}
}
class Program
{
static void Main(string[] args)
{
Order order = new MicrosoftOrder();
order.PlaceOrder(); // Default Order;
Order orderWithAsync = new AppleOrder(order);
orderWithAsync.PlaceOrder(); // Place order with asycn
Order orderWithAsyncAndlogging = new GoogleOrder(orderWithAsync);
orderWithAsyncAndlogging.PlaceOrder(); // order with asynch and logging.
}
}

Appropriate design/design pattern for this problem?

I previously posted this, but I guess it was too verbose and irrelevant. My question is also like this. One poster in the second link said the answer (of why you can't do the code below) was a problem of design, specifically "bad use of inheritance". So I'd like to check this issue again with the experts at StackOverflow and see if this is really an issue of "bad inheritance" - but more importantly, how to fix the design.
Like the poster, I'm also confused about the Factory method and how I can apply it. It seems the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class and do not add their own properties. But, as you will see below, my concrete classes build upon the abstract base class and add extra properties.
The Base Class We Build Upon:
public abstract class FlatScreenTV
{
public string Size { get; set; }
public string ScreenType { get; set; }
}
Extension Class Examples:
public class PhillipsFlatScreenTV : FlatScreenTV
{
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity { get; set; }
}
public class SamsungFlatScreenTV : FlatScreenTV
{
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime { get; set; }
}
Let's say there are more extension classes for more brands of flat screen TVs. And then, let's say we stick them all into a generic List:
public static void Main()
{
List<FlatScreenTV> tvList = new List<FlatScreenTV>();
tvList.Add(new PhillipsFlatScreenTV());
tvList.Add(new SamsungFlatScreenTV());
tvList.Add(new SharpFlatScreenTV());
tvList.Add(new VizioFlatScreenTV());
FlatScreenTV tv = tvList[9]; // Randomly get one TV out of our huge list
}
The Problem:
I want to access the specific properties of whatever 'original' brand TV this variable belongs to. I know the brand because if I call tv.GetType(), it returns the correct 'original' type - not FlatScreenTV. But I need to be able to cast tv from FlatScreenTV back to its original type to be able to access the specific properties of each brand of flat-screen TVs.
Question #1: How can I dynamically cast that, properly - without makeshift hacks and huge if-else chains to brute-guess the 'original' type?
After browsing around similar design issues, most answers are: you can't. Some people say to look at the Factory Pattern, and others say to revise the design using interfaces, but I don't know how to use either to solve this problem.
Question #2: So, how should I design these classes so that I can access the original type's specific properties in the context above?
Question #3: Is this really bad inheritance?
Your design violates the "Liskov Substitution Principle". In other words, the code that deals with items from your list of FlatScreenTV shouldn't know or care what derived type is.
Say your code needs to create a custom remote control GUI. It might be enough to simply know the names and types of the properties of each TV to auto-generate the UI. In which case you could do something like this to expose the custom properties from the base class:
public abstract class FlatScreenTV
{
public FlatScreenTV()
{
CustomProperties = new Dictionary<string,object>();
}
public Dictionary<string,object> CustomProperties { get; private set; }
public string Size { get; set; }
public string ScreenType { get; set; }
}
public class PhillipsFlatScreenTV : FlatScreenTV
{
public PhillipsFlatScreenTV()
{
BackLightIntensity = 0;
}
// Specific to Phillips TVs. Controls the backlight intensity of the LCD screen.
public double BackLightIntensity
{
get { return (double)CustomProperties["BackLightIntensity"]; }
set { CustomProperties["BackLightIntensity"] = value; }
}
}
public class SamsungFlatScreenTV : FlatScreenTV
{
public SamsungFlatScreenTV()
{
AutoShutdownTime = 0;
}
// Specific to Samsung TVs. Controls the time until the TV automatically turns off.
public int AutoShutdownTime
{
get { return (int)CustomProperties["AutoShutdownTime"]; }
set { CustomProperties["AutoShutdownTime"] = value; }
}
}
If you really do need to be working directly with the derived types, then you should instead consider moving to a plugin based architecture. For example, you might have a factory method like this:
IRemoteControlGUI GetRemoteControlGUIFor(FlatScreenTV tv)
which would scan your plugins and find the one that knew how to build the UI for the particular type of FlatScreenTV you passed in. This means that for every new FlatScreenTV you add, you also need to create a plugin that knows how to make its remote control GUI.
Factory Pattern would be the best way to go
I can offer a partial answer:
Firstly read up on Liskov's Substitution Principle.
Secondly you are creating objects that inherit from FlatScreenTV, but apparently for no purpose as you want to refer to them by their SubType (SpecificTVType) and not their SuperType (FlatScreenTV) - This is bad use of Inheritance as it is NOT using inheritance lol.
If your code wants to access properties particular to a given type, then you really want this code encapsulated within that type. Otherwise everytime you add a new TV type, all the code that handles the TV list would need to be updated to reflect that.
So you should include a method on FlatScreenTV that does x, and override this in TV's as required.
So basically in your Main method above, instead of thinking I want to be dealing with TVTypeX, you should always refer to the basetype, and let inheritance and method overriding handle the specific behaviour for the subtype you are actually dealing with.
Code eg.
public abstract class FlatScreenTV
{
public virtual void SetOptimumDisplay()
{
//do nothing - base class has no implementation here
}
}
public class PhilipsWD20TV
{
public int BackLightIntensity {get;set;}
public override void SetOptimumDisplay()
{
//Do Something that uses BackLightIntensity
}
}
"the factory method is for multiple concrete classes that have the exact same implementation as the abstract base class [interface] and do not add their own properties."
No, speaking more practical, than theorical, the factory method can provide you with objects of concrete classes, in which the concrete classes, must have some common methods and interfaces, but, also some additional specific attributes.
Sometimes I use a method that creates the same class object every time I called, and I need to call it several times, and sometimes I use a method that create several different class objects, and that maybe be confusing, maybe another question.
And, your further comment about a switch sentence, with many options, when using the factory pattern, you usually provide an identifier for the concrete class / concrete object. This can be a string, an integer, an special type id, or an enumerated type.
You could use an integer / enum ID instead, and use a collection to lookup for the concrete class.
You can still leverage a factory. The point of a factory IMO is to put all the heavy lifting of constructing your various TVs in one place. To say categorically "a factory is for multiple concrete classes that have the exact same implementation as the abstract base class" is forgetting about polymorphism.
There is no law that says you cannot use a factory pattern because the sub classes declare unique properties and methods. But the more you can make use of polymorphism, the more a factory pattern makes sense. Also as a general guideline, IMHO, the more complexity that must go into constructing from the base the better off you are in the long run using a factory because you are "encapsulating change" - that is, constructing concrete classes is likely to change due to differing requirements and inherent construction complexity (a design analysis decision, to be sure) . And that change is in a single class - the factory.
Try this: Define everything in the abstract class and then for a given TV subclass either write concrete-specific code, and for those that don't apply write some standard "I don't do that" code.
Think about all the things your TVs do in generic terms: turn on, turn off, etc. Write a virtual method shell in the base class for all the generic things a TV does - this is a simple example of the template method pattern by the way. Then override these in the concrete classes as appropriate.
There are other things you can do in the base class to make it more fundgeable (that's a technical term meaning "reference subclasses as the base class, but do sub-classy things").
Define delegate methods (very powerful yet under-utilized)
use params[] for dynamic method parameter lists
Make Property delegates
Static methods
Declare Properties and methods "abstract" - forces sub-class implementation, vis-a-vis "virtual"
Hide inherited stuff in the sub class (generally using "new" keyword to communicate that it's on purpose)
If construction parameters are numerous or complex, create a class specifically designed to pass configuration to the factory's build method.
public class TVFactory {
public TV BuildTV(Brands thisKind) {
TV newSet;
switch (thisKind) {
case Brands.Samsung :
Samsung aSamsungTV = new Samsung();
aSamsungTV.BacklightIntensity = double.MinVal;
aSamsungTV.AutoShutdownTime = 45; //oops! I made a magic number. My bad
aSamsungTV.SetAutoShutDownTime = new delegate (newSet.SetASDT);
newSet = aSamsungTV;
break;
. . .
} // switch
}
//more build methods for setting specific parameters
public TV BuildTV (Brands thisKind, string Size) { ... }
// maybe you can pass in a set of properties to exactly control the construction.
// returning a concrete class reference violates the spirit of object oriented programming
public Sony BuildSonyTV (...) {}
public TV BuildTV (Brands thisKind, Dictionary buildParameters) { ... }
}
public class TV {
public string Size { get; set; }
public string ScreenType { get; set; }
public double BackLightIntensity { get; set; }
public int AutoShutdownTime { get; set; }
//define delegates to get/set properties
public delegate int GetAutoShutDownTime ();
public delegate void SetAutoShutDownTime (object obj);
public virtual TurnOn ();
public virtural TurnOff();
// this method implemented by more than one concrete class, so I use that
// as an excuse to declare it in my base.
public virtual SomeSonyPhillipsOnlything () { throw new NotImplementedException("I don't do SonyPhillips stuff"); }
}
public class Samsung : TV {
public Samsung() {
// set the properties, delegates, etc. in the factory
// that way if we ever get new properties we don't open umpteen TV concrete classes
// to add it. We're only altering the TVFactory.
// This demonstrates how a factory isolates code changes for object construction.
}
public override void TurnOn() { // do stuff }
public override void TurnOn() { // do stuff }
public void SamsungUniqueThing () { // do samsung unique stuff }
internal void SetASDT (int i) {
AutoShutDownTime = i;
}
}
// I like enumerations.
// No worries about string gotchas
// we get intellense in Visual Studio
// has a documentation-y quality
enum Brands {
Sony
,Samsung
,Phillips
}

Question about Factory Design Architecture

Consider this example
The Interface
interface IBusinessRules
{
string Perform();
}
The Inheritors
class Client1BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 1 Performed";
}
}
class Client2BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 2 Performed";
}
}
class Client3BusinessRules: IBusinessRules
{
public string Perform()
{
return "Business rule for Client 3 Performed";
}
}
The factory class
class BusinessRulesFactory
{
public IBusinessRules GetObject(int clientIdentityCode)
{
IBusinessRules objbase = null;
switch (clientIdentityCode)
{
case 1:
objbase = new Client1BusinessRules();
break;
case 2:
objbase = new Client2BusinessRules();
break;
case 3:
objbase = new Client3BusinessRules();
break;
default:
throw new Exception("Unknown Object");
}
return objbase;
}
}
sample usage:
class Program
{
static void Main(string[] args)
{
BusinessRulesFactory objfactory = new BusinessRulesFactory ();
IBusinessRulesFactory objBase = objfactory.GetObject(2);
Console.WriteLine(objBase.Perform());
objBase = objfactory.GetObject(3);
Console.WriteLine(objBase.Perform());
Console.Read();
}
}
My question is, how about I add another method on the ALgorithm1 Class
but not in the interface because im going to just use it on special scenario?
class Client1BusinessRules: IBusinessRules
{
public string Perform()
{
return "Client1 Business rules is Performed";
}
public string Calculate()
{
return "Additional functionality for CLient1";
}
}
how Am I suppose to call that on the UI something like this
objBase = objfactory.GetObject(1);
Console.WriteLine(objBase.Calculate());
Is there any other solution? thanks in advance
EDIT: I rewrite it to resemble my current project design
I presume you are using the factory class in order to:
have a standard facade accepting parameters that lead to business rule selection and provisioning
encapsulate business rule provisioning
decouple the users from actual implementations of IBusinessRules
Hence I would solve your problem by introducing new interface
interface IComputableRules : IBusinessRules
{
string Calculate();
}
As long as you follow the interface-based design, there's nothing wrong about casting the actual instance to an interface different from IBusinessRules.
IBusinessRules businessRule = objFactory.GetObject(...some input...)
...
// check if the computable service is supported and print the result
IComputableRules computable = businessRule as IComputableRules;
if (computable)
{
Console.WriteLine(computable.Calculate());
}
Here you can think of you business rule classes as service providers, that guarantee some basic service, plus optional additional services depending on the nature of the business rule.
Note: By turning the BusinessRulesFactory into a generic class you might make the indication of a specific service a part of the factory contract, and make sure the returned business rule implementation will support a particular (otherwise optional) service.
class BusinessRulesFactory<TService> where TService : IBusinessRules
{
public TService GetObject(int clientIdentityCode)
{
// ... choose business rule in respect to both clientIdentityCode and TService
}
}
In case where you wouldn't require a specific additional service to be available, you'd just use IBusinessRules as the actual type parameter.
The whole point of the factory pattern is to return the proper implementation of a contract so that the consumer shouldn't worry about how to instantiate it but simply invoke its methods. You could always test the actual type, cast to it and invoke the method but that's a very bad design and I wouldn't recommend it. The consumer shouldn't know anything about the actual type. You will need to rethink your design.
If you want to stick to the current architecture you can introduce a new interface declaration
interface ICalculationRules
{
string Calculate();
}
Now let modify Client1BusinessRules by adding the interface declaration:
class Client1BusinessRules: IBusinessRules, ICalculationRules
{
// everything remains the same
}
Modify your calling code like this:
var objBase = objfactory.GetObject(1);
Console.WriteLine(objBase.Calculate());
var calcBase = obj as ICalculationRules;
if (calcBase != null) calculable.Calculate();
Maintenance implication: Every time you introduce a new interface, you have to touch all your calling code. Since you posted that this code is placed in the UI code, this can get quite a mess.
Each interface you are introducing just means added behaviour to a class. If you have a large range of different behaviours, then the solution above my not feel right, because there is always the need to use the as operation and conditional execution a method. If you want to stick to some classic design pattern this variability of behaviour can be countered with the Decorator Pattern or the Strategy Pattern. They can be smoothly combined with the Factory Pattern.
There are many approaches that can be employed in this case, and it depends on the cost you're willing to put in order to get the value.
For example, you can go with simple casting. You'll get the algorithm object from the factory, cast it to the proper (specific) algorithm object, and then call the "Calculate" function.
Another option - a much more generic one, that would also require much more code - would be to supply a querying mechanism within the base class, that will supply information about the available functionality within the object. This is somewhat comparable to querying for interfaces in COM.
The important questions you need to ask yourself is:
1. How many times will you need to implement specific functionality?
2. Is there a way you can solve the problem with added polymorphism stemming from the base class?
3. Will users of the derived objects know that they are using the specific object, or do you want them to be ignorant of the actual type?
In general what I personally do in such cases is start with the simplest solution (in this case, specific casting and calling the function), and go back and refactor as I go, when I have some more data about the domain. If you're sensitive to "smelly code", you'll get to a point where you see there's too much clutter and you'll refactor it into a better solution.
I would modify it like this
interface IBusinessRules
{
string Perform();
bool CanCalculate { get; }
string Calculate();
}
and add an abstract base class (optional but recommended for further extensibility)
public abstract class BusinessRules : IBusinessRules {
protected BusinessRules() {
}
protected virtual bool CanCalculateCore() {
return false; // Cannot calculate by default
}
protected virtual string CalculateCore() {
throw new NotImplementedException("Cannot calculate");
}
protected abstract string PerformCore();
#region IBusinessRules Members
public string Perform()
{
return PerformCore();
}
public bool CanCalculate
{
get { return CanCalculateCore(); }
}
public string Calculate()
{
return CalculateCore();
}
#endregion
}
So the call site now looks neat:
objBase = objfactory.GetObject(1);
if (objBase.CanCalculate) {
Console.WriteLine(objBase.Calculate());
}
One big problem of extending the interface is, it gives the caller no hint at all that you might support that interface as well.
This is a domain modelling issue and relates to what you mean by BusinessRule and IBase in your problem domain.
What is IBase? Sounds like it should be called IBusinessRule. In which case, what does Calculate mean in the context of a "business rule". If it has a generic meaning in your domain then IBusinessRule should implement it, as should the other classes, even if only as an empty method.
If it doesn't have generic meaning in your domain then your class should implement another interface ICalculable (IAlgorithm?) that has Calculate, which you call as:
ICalculable calculable = obj as ICalculable;
if ( calculable != null ) calculable.Calculate();

Categories