Design pattern for a user interface with extensible functionality - oop

Say I am writing a user interface for a hardware accessory. There are two versions of the accessory - let's say Widget Lite and Widget Pro.
Widget Pro can do everything that Widget Lite can do, but with a few more options and can do a few things that Widget Lite can't. In more detail, Widget Lite has one channel, widget Pro has two, so when it comes to something analogous to volume control, I need only one control for the Lite, but two for the Pro allowing independent control.
In my first attempt at building an application to handle this, I had the class representing Widget Pro extend Widget Lite, but then I've ended up with all sorts of conditional cases to handle the differences which seems ugly. Does anyone know a suitable design pattern to help with such a situation? My imagination is drawing a blank in coming up with synonymous situations that might help in my search.

I would start off by looking at the plug in pattern (one of the forms of Dependency Inversion).
Try and abstract an interface common to the Lite and Pro versions, e.g.
interface IBaseWidget
{
IControl CreateVolumeControl();
// ... etc
}
In separate assemblies / dlls, implement your Lite and Pro widgets:
class LiteWidget : IBaseWidget
{
int _countCreated = 0;
IControl CreateVolumeControl()
{
_countCreated++;
if (_countCreated > 1)
{
throw new PleaseBuyTheProVersionException();
}
}
}
Since you don't want to distribute the Pro version with the Lite deployment, you will need to load the dlls at run time, e.g. by Convention (e.g. Your base app Looks around for DLL's named *Widget.dll), or by Configuration, which finds the applicable concrete implementation of IBaseWidget. As per #Bartek's comment, you ideally don't want your base engine classfactory to 'know' about specific concrete classes of IBaseWidget.

Visitor pattern might be useful for you. Check dofactory.
Visitor class...
...declares a Visit operation for each class of ConcreteElement in the
object structure. The operation's name and signature identifies the
class that sends the Visit request to the visitor. That lets the
visitor determine the concrete class of the element being visited.
Then the visitor can access the elements directly through its
particular interface
This is similar to Abstract class implementation as told by Vikdor.
Here is a wiki link for this.
The visitor pattern requires a programming language that supports
single dispatch and method overloading.
I have provided a very simple implementation using the visitor pattern for your requirement of different channels and volume settings for WidgetLite and Pro. I have mentioned in comments where the visitor pattern will greatly help you in reducing the if-else calls.
The basic philosophy is that you pass the control (ex. volume) to the widget and it will know how to use it as required. Hence, control object itself has a very simplified implementations. Each widget's code remains together!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WidgetVisitor
{
//This is the widget interface. It ensures that each widget type
//implements a visit functionality for each control. The visit function
//is overloaded here.
//The appropriate method is called by checking the parameter and this
//avoids the if-then logic elegantly
public interface Widget
{
void visit(Volume vol);
void visit(Channel chan);
void Display(AllControls ac);
}
//This is the interface which defines the controls. Each control that
//inherits this interface needs to define an "accept" method which
//calls the appropriate visit function of the right visitor,
//with the right control parameter passed through its call!
//This is how the double dispatch works.
//Double dispatch: A mechanism that dispatches a function call to different concrete
//functions depending on the runtime types of two objects involved in the call.
public interface WidgetControls
{
void accept(Widget visitor);
}
//I have implemented the volume control and channel control
//Notice how the code for defining each control is the SAME
//in visitor pattern! This is double dispatch in action
public class Volume : WidgetControls
{
public int volLevel { get; set; }
public int volJazz { get; set; }
public int volPop { get; set; }
public void accept(Widget wc)
{
wc.visit(this);
}
}
public class Channel : WidgetControls
{
public int channelsProvided { get; set; }
public int premiumChannels { get; set; }
public void accept(Widget wc)
{
wc.visit(this);
}
}
//Widget lite implementation. Notice the accept control implementation
//in lite and pro.
//Display function is an illustration on an entry point which calls the
//other visit functions. This can be replaced by any suitable function(s)
//of your choice
public class WidgetLite : Widget
{
public void visit(Volume vol)
{
Console.WriteLine("Widget Lite: volume level " + vol.volLevel);
}
public void visit(Channel cha)
{
Console.WriteLine("Widget Lite: Channels provided " + cha.channelsProvided);
}
public void Display(AllControls ac)
{
foreach (var control in ac.controls)
{
control.accept(this);
}
Console.ReadKey(true);
}
}
//Widget pro implementation
public class WidgetPro : Widget
{
public void visit(Volume vol)
{
Console.WriteLine("Widget Pro: rock volume " + vol.volLevel);
Console.WriteLine("Widget Pro: jazz volume " + vol.volJazz);
Console.WriteLine("Widget Pro: jazz volume " + vol.volPop);
}
public void visit(Channel cha)
{
Console.WriteLine("Widget Pro: Channels provided " + cha.channelsProvided);
Console.WriteLine("Widget Pro: Premium Channels provided " + cha.premiumChannels);
}
public void Display(AllControls ac)
{
foreach (var control in ac.controls)
{
control.accept(this);
}
Console.ReadKey(true);
}
}
//This is a public class that holds and defines all the
//controls you want to define or operate on for your widgets
public class AllControls
{
public WidgetControls [] controls { get; set; }
public AllControls(int volTot, int volJazz, int volPop, int channels, int chanPrem)
{
controls = new WidgetControls []
{
new Volume{volLevel = volTot, volJazz = volJazz, volPop = volPop},
new Channel{channelsProvided = channels, premiumChannels = chanPrem}
};
}
}
//finally, main function call
public class Program
{
static void Main(string[] args)
{
AllControls centralControl = new AllControls(3, 4, 2, 5, 10);
WidgetLite wl = new WidgetLite();
WidgetPro wp = new WidgetPro();
wl.Display(centralControl);
wp.Display(centralControl);
}
}
}

I would do it as follows:
AbstractWidget (Abstract class)
/\
/ \
/ \
/ \
/ \
WidgetLite WidgetPro
The common code would go into the AbstractWidget (abstract because, it shouldn't be instantiated) and the behaviour that is different between these two classes would go into the concrete classes.

I would strongly suggest that you have a base Widget class which both Widget Lite and Widget Pro derive from.
public class Widget {}
public class WidgetLite : Widget {}
public class WidgetPro : Widget {}
Have the properties/methods which are shared by both Pro and Lite inside the base class. This is a much cleaner design for you.

Related

How does State design pattern satisfy the open closed design principle

I recently just started learning design patterns using java and I was a bit confused and wondering how does state design pattern satisfy the open closed design principle as I couldn't online resource that has a concrete explanation on this..
I really like this book Head First Design Patterns. It has a lot of examples with super simple explanations!
Imagine you have a game where hero can be any person in the world. Let's call him as Hero.
He can run, swim and fly. You have a button where you can change its state or shape.
The code of Hero would look like this:
public class Hero
{
IState _state;
public Hero()
{
_state = new SpiderManState();
}
public void Run()
{
_state.Run();
}
public void Swim()
{
_state.Swim();
}
public void Fly()
{
_state.Fly();
}
public void ChangeShape()
{
_state = _state.ChangeChape();
}
}
Interfaces of IState would look like this:
public interface IState
{
void Run();
void Swim();
void Fly();
IState ChangeChape();
}
And concrete states look like this:
public class SpiderManState : IState
{
public void Fly()
{
Console.WriteLine("Spiderman is flying");
}
public void Run()
{
Console.WriteLine("Spiderman is running");
}
public void Swim()
{
Console.WriteLine("Spiderman is swimming");
}
public IState ChangeChape()
{
return new IronManState();
}
}
and IronManState would look like this:
public class IronManState : IState
{
public void Fly()
{
Console.WriteLine("IronMan is flying");
}
public void Run()
{
Console.WriteLine("IronMan is running");
}
public void Swim()
{
Console.WriteLine("IronMan is swimming");
}
public IState ChangeChape()
{
return new SpiderManState();
}
}
How does State design pattern satisfy the open closed design principle
Next time when you will want to add new State of Hero, you can add just new class like SomeSuperManState without editing Hero class.
So our Hero class is closed for modification, but it is opened for extension.
The state pattern is typically used as an extension of the strategy pattern that allows the strategy to be executed in steps or phases over multiple calls.
It implements the open/closed principle in the same way that the strategy pattern does.
Think of an executing workflow, which responds to events differently depending on the progress so far and which step is currently pending. When it receives an event, it dispatches it to the current step (the state), and the step takes action that can include changing the current step to one of the following ones.
The alternative to the state pattern is just implementing the whole strategy in a single object that stores internal state. The state pattern is used to divide up the responsibilities and allow the states to be implemented independently. It's also naturally emerges when the state must be persisted between calls.

How to do logic based on object ID

Suppose I have a game, where there are buildings sorted by type. Each type is represented as a separate class, but sometimes I have to do some uncommon logic for the buildings of the same type. How could one implement this kind of behaviour?
For example, I can identify buildings by ID, so I can have a giant switch or command pattern inside the building type class. But I think that something is not right with this approach.
Another approach is to have different class for any divergent logic. But this proposes a lot of small classes.
This is what polymorphism aims to solve, and one of the big differences between procedural and oop programming. You can achieve it through extending a base class, or by implementing an interface. Here is extending a base class:
public abstract class Building {
abstract void destroy();
}
public BrickBuilding extends Building {
#Override
public void destroy() {
bricks.fallToGround();
}
}
public HayBuilding extends Building {
#Override
public void destroy() {
straw.blowInWind();
}
}
In places in your code where you would have used a switch statement to switch on building type, just hold a reference to the abstract Building type, and call method destroy() on it:
public class BuildingDestroyer {
public void rampage() {
for(Building building : allTheBuildings) {
// Could be a BrickBuilding, or a HayBuilding
building.destroy();
}
}
}
Or, to address your concern about having a lot of small types, you can 'inject' a destroy behaviour you want into a common building type, like so...albeing, you will end up with a lot of different destroy behaviour classes too...so, this might not be a solution.
public interface DestroyBehaviour {
void destroy(Building building);
}
public class Building {
private int id;
public DestroyBehaviour destroyBehaviour;
public Building(int id, DestroyBehaviour destroyBehaviour) {
this.id = id;
this.destroyBehaviour = destroyBehaviour;
}
public void destroy() {
destroyBehaviour.destroy(this); // or something along those lines;
}
}
You can get rid of the giant switch by having a BuildingFactory class which exposes a registerBuildingType(typeName, instanceCreatorFunc) method, that each building class calls (from a static initialize method for example) and that gets called with a unique string for that class (class name would suffice) and a static "create" method that returns a new instance.
This approach also has the advantage of being able to load new buildings from dynamically linked libraries.

OO programming issue - State Design Pattern

I have spent the last day trying to work out which pattern best fits my specific scenario and I have been tossing up between the State Pattern & Strategy pattern. When I read examples on the Internet it makes perfect sense... but it's another skill trying to actually apply it to your own problem. I will describe my scenario and the problem I am facing and hopefully someone can point me in the right direction.
Problem: I have a base object that has different synchronization states: i.e. Latest, Old, Never Published, Unpublished etc. Now depending on what state the object is in the behaviour is different, for example you cannot get the latest version for a base object that has never been published. At this point it seems the State design pattern is best suited... so I have implemented it and now each state has methods such as CanGetLatestVersion, GetLatestVersion, CanPublish, Publish etc.
It all seems good at this point. But lets say you have 10 different child objects that derive from the base class... my solution is broken because when the "publish" method is executed for each state it needs properties in the child object to actually carry out the operation but each state only has a reference to the base object. I have just spent some time creating a sample project illustrating my problem in C#.
public class BaseDocument
{
private IDocumentState _documentState;
public BaseDocument(IDocumentState documentState)
{
_documentState = documentState;
}
public bool CanGetLatestVersion()
{
return _documentState.CanGetLatestVersion(this);
}
public void GetLatestVersion()
{
if(CanGetLatestVersion())
_documentState.CanGetLatestVersion(this);
}
public bool CanPublish()
{
return _documentState.CanPublish(this);
}
public void Publish()
{
if (CanPublish())
_documentState.Publish(this);
}
internal void Change(IDocumentState documentState)
{
_documentState = documentState;
}
}
public class DocumentSubtype1 : BaseDocument
{
public string NeedThisData { get; set; }
}
public class DocumentSubtype2 : BaseDocument
{
public string NeedThisData1 { get; set; }
public string NeedThisData2 { get; set; }
}
public interface IDocumentState
{
bool CanGetLatestVersion(BaseDocument baseDocument);
void GetLatestVersion(BaseDocument baseDocument);
bool CanPublish(BaseDocument baseDocument);
bool Publish(BaseDocument baseDocument);
SynchronizationStatus Status { get; set; }
}
public class LatestState : IDocumentState
{
public bool CanGetLatestVersion(BaseDocument baseDocument)
{
return false;
}
public void GetLatestVersion(BaseDocument baseDocument)
{
throw new Exception();
}
public bool CanPublish(BaseDocument baseDocument)
{
return true;
}
public bool Publish(BaseDocument baseDocument)
{
//ISSUE HERE... I need to access the properties in the the DocumentSubtype1 or DocumentSubType2 class.
}
public SynchronizationStatus Status
{
get
{
return SynchronizationStatus.LatestState;
}
}
}
public enum SynchronizationStatus
{
NeverPublishedState,
LatestState,
OldState,
UnpublishedChangesState,
NoSynchronizationState
}
I then thought about implementing the state for each child object... which would work but I would need to create 50 classes i.e. (10 children x 5 different states) and that just seems absolute crazy... hence why I am here !
Any help would be greatly appreciated. If it is confusing please let me know so I can clarify!
Cheers
Let's rethink this, entirely.
1) You have a local 'Handle', to some data which you don't really own. (Some of it is stored, or published, elsewhere).
2) Maybe the Handle, is what we called the 'State' before -- a simple common API, without the implementation details.
3) Rather than 'CanPublish', 'GetLatestVersion' delegating from the BaseDocument to State -- it sounds like the Handle should delegate, to the specific DocumentStorage implementation.
4) When representing external States or Storage Locations, use of a separate object is ideal for encapsulating the New/Existent/Deletion state & identifier, in that storage location.
5) I'm not sure if 'Versions' is part of 'Published Location'; or if they're two independent storage locations. Our handle needs a 'Storage State' representation for each independent location, which it will store to/from.
For example:
Handle
- has 1 LocalCopy with states (LOADED, NOT_LOADED)
- has 1 PublicationLocation with Remote URL and states (NEW, EXIST, UPDATE, DELETE)
Handle.getVersions() then delegates to PublicationLocation.
Handle.getCurrent() loads a LocalCopy (cached), from PublicationLocation.
Handle.setCurrent() sets a LocalCopy and sets Publication state to UPDATE.
(or executes the update immediately, whichever.)
Remote Storage Locations/ Transports can be subtyped for different methods of accessing, or LocalCopy/ Document can be subtyped for different types of content.
THIS, I AM PRETTY SURE, IS THE MORE CORRECT SOLUTION.
[Previously] Keep 'State' somewhat separate from your 'Document' object (let's call it Document, since we need to call it something -- and you didn't specify.)
Build your heirarchy from BaseDocument down, have a BaseDocument.State member, and create the State objects with a reference to their Document instance -- so they have access to & can work with the details.
Essentially:
BaseDocument <--friend--> State
Document subtypes inherit from BaseDocument.
protected methods & members in Document heirarchy, enable State to do whatever it needs to.
Hope this helps.
Many design patterns can be used to this kind of architecture problem. It is unfortunate that you do not give the example of how you do the publish. However, I will state some of the good designs:
Put the additional parameters to the base document and make it
nullable. If not used in a document, then it is null. Otherwise, it
has value. You won't need inheritance here.
Do not put the Publish method to the DocumentState, put in the
BaseDocument instead. Logically, the Publish method must be part
of BaseDocument instead of the DocumentState.
Let other service class to handle the Publishing (publisher
service). You can achieve it by using abstract factory pattern. This
way, you need to create 1:1 document : publisher object. It may be
much, but you has a freedom to modify each document's publisher.
public interface IPublisher<T> where T : BaseDocument
{
bool Publish(T document);
}
public interface IPublisherFactory
{
bool Publish(BaseDocument document);
}
public class PublisherFactory : IPublisherFactory
{
public PublisherFactory(
IPublisher<BaseDocument> basePublisher
, IPublisher<SubDocument1> sub1Publisher)
{
this.sub1Publisher = sub1Publisher;
this.basePublisher = basePublisher;
}
IPublisher<BaseDocument> basePublisher;
IPublisher<SubDocument1> sub1Publisher;
public bool Publish(BaseDocument document)
{
if(document is SubDocument1)
{
return sub1Publisher.Publish((SubDocument1)document);
}
else if (document is BaseDocument)
{
return basePublisher.Publish(document);
}
return false;
}
}
public class LatestState : IDocumentState
{
public LatestState(IPublisherFactory factory)
{
this.factory = factory;
}
IPublisherFactory factory;
public bool Publish(BaseDocument baseDocument)
{
factory.Publish(baseDocument);
}
}
Use Composition over inheritance. You design each interface to each state, then compose it in the document. In summary, you can has 5 CanGetLatestVersion and other composition class, but 10 publisher composition class.
More advancedly and based on the repository you use, maybe you can use Visitor pattern. This way, you can has a freedom to modify each publishing methods. It is similiar to my point 3, except it being declared in one class. For example:
public class BaseDocument
{
}
public class SubDocument1 : BaseDocument
{
}
public class DocumentPublisher
{
public void Publish(BaseDocument document)
{
}
public void Publish(SubDocument1 document)
{
// do the prerequisite
Publish((BaseDocument)document);
// do the postrequisite
}
}
There may be other designs available but it is dependent to how you access your repository.

Refactoring Switching On Types Code Smell When Adding Method to Type Seems Inappropriate

Let's say I have the following method that, given a PaymentType, sends an appropriate payment request to each facility from which the payment needs to be withdrawn:
public void SendRequestToPaymentFacility(PaymentType payment) {
if(payment is CreditCard) {
SendRequestToCreditCardProcessingCenter();
} else if(payment is BankAccount) {
SendRequestToBank();
} else if(payment is PawnTicket) {
SendRequestToPawnShop();
}
}
Obviously this is a code smell, but when looking for an appropriate refactoring, the only examples I have seen involve cases where the code executed within the conditionals are clearly the responsibility of the class itself, e.g. with the standard example given:
public double GetArea(Shape shape) {
if(shape is Circle) {
Circle circle = shape As Circle;
return circle.PI * (circle.radius * circle.radius);
} else if(shape is Square) {
Square square = shape as Square;
return square.length * square.width;
}
}
GetArea() seems like a pretty reasonable responsibility for each Shape subclass, and can of course be refactored nicely:
public class Shape
{
/* ... */
public abstract double GetArea();
}
public class Circle
{
public override double GetArea()
{
return PI * (radius * radius);
}
}
However, SendRequestToPaymentFacility() does not seem like an appropriate responsibility for a PaymentType to have. (and would seem to violate the Single Responsibility Principle). And yet I need to send a request to an appropriate PaymentFacility based on the type of PaymentType - what is the best way to do this?
You could consider adding a property or method to your CandyBar class which indicates whether or not the CandyBar contains nuts. Now your GetProcessingPlant() method does not have to have knowledge of the different types of CandyBars.
public ProcessingPlant GetProcessingPlant(CandyBar candyBar) {
if(candyBar.ContainsNuts) {
return new NutProcessingPlant();
} else {
return new RegularProcessingPlant();
}
}
One option would be to add an IPaymentFacility interface parameter to the constructors for the individual PaymentType descendants. The base PaymentType could have an abstract PaymentFacility property; SendRequestToPaymentFacility on the base type would delegate:
public abstract class PaymentType
{
protected abstract IPaymentFacility PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process(this);
}
}
public interface IPaymentFacility
{
void Process(PaymentType paymentType);
}
public class BankAccount : PaymentType
{
public BankAccount(IPaymentFacility paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility _paymentFacility;
}
Rather than wiring up the dependency injection manually, you could use a DI/IoC Container library. Configure it so that a BankAccount got a Bank, etc.
The downside is that the payment facilities would only have access to the public (or possibly internal) members of the base-class PaymentType.
Edit:
You can actually get at the descendant class members by using generics. Either make SendRequestToPaymentFacility abstract (getting rid of the abstract property), or get fancy:
public abstract class PaymentType<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
protected abstract IPaymentFacility<TPaymentType> PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process((TPaymentType) this);
}
}
public class BankAccount : PaymentType<BankAccount>
{
public BankAccount(IPaymentFacility<BankAccount> paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility<BankAccount> PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility<BankAccount> _paymentFacility;
}
public interface IPaymentFacility<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
void Process(TPaymentType paymentType);
}
public class Bank : IPaymentFacility<BankAccount>
{
public void Process(BankAccount paymentType)
{
}
}
The downside here is coupling the Bank to the BankAccount class.
Also, Eric Lippert discourages this, and he makes some excellent points.
One approach you can take here is to use the Command pattern. In this case, you would create and queue up the appropriate command (e.g. Credit Card, Bank Account, Pawn Ticket) rather than calling a particular method. Then you could have separate command processors for each command that would take the appropriate action.
If you don't want the conditional complexity here, you could raise a single type of command that included the payment type as a property, and then a command processor could be responsible for figuring out how to handle that request (with the appropriate payment processor).
Either of these could help your class follow Single Responsibility Principle by moving details of payment processing out of it.

Force lazy entity to load real instance

I have a proxy for a lazy entity which has been created in the session by loading a child entity. A subsequent fetch on the parent entity only returns the NH proxy. I need the actual instance to check the type (the entity has joined subclasses). I must be missing something, but I can't find a way to do this. Session.Refresh(proxy) does not appear to help, nor does any flavour of HQL that I've tried.
Can anyone help?
In my opinion, rather then solving this problem, you should rather rethink your design. Are you absolutely sure, that you can't use polymorphism in this situation - either directly make entity responsible for operation you're trying to perform or use visitor pattern. I came across this issue few times and always decided to change design - it resulted in clearer code. I suggest you do the same, unless you're absolutely sure that relying on type is the best solution.
The problem
In order to have example with at least some resemblance to the real world, let's suppose you have following entities:
public abstract class Operation
{
public virtual DateTime PerformedOn { get; set; }
public virtual double Ammount { get; set; }
}
public class OutgoingTransfer : Operation
{
public virtual string TargetAccount { get; set; }
}
public class AtmWithdrawal : Operation
{
public virtual string AtmAddress { get; set; }
}
It'd naturally be a small part of much larger model. And now you're facing a problem: for each concrete type of Operation, there's a different way to display it:
private static void PrintOperation(Operation operation)
{
Console.WriteLine("{0} - {1}", operation.PerformedOn,
operation.Ammount);
}
private static void PrintOperation(OutgoingTransfer operation)
{
Console.WriteLine("{0}: {1}, target account: {2}",
operation.PerformedOn, operation.Ammount,
operation.TargetAccount);
}
private static void PrintOperation(AtmWithdrawal operation)
{
Console.WriteLine("{0}: {1}, atm's address: {2}",
operation.PerformedOn, operation.Ammount,
operation.AtmAddress);
}
Simple, overloaded methods will work in simple case:
var transfer = new OutgoingTransfer
{
Ammount = -1000,
PerformedOn = DateTime.Now.Date,
TargetAccount = "123123123"
};
var withdrawal = new AtmWithdrawal
{
Ammount = -1000,
PerformedOn = DateTime.Now.Date,
AtmAddress = "Some address"
};
// works as intended
PrintOperation(transfer);
PrintOperation(withdrawal);
Unfortunately, overloaded methods are bound at compile time, so as soon as you introduce an array/list/whatever of operations, only a generic (Operation operation) overload will be called.
Operation[] operations = { transfer, withdrawal };
foreach (var operation in operations)
{
PrintOperation(operation);
}
There are two solutions to this problem, and both have downsides. You can introduce an abstract/virtual method in Operation to print information to selected stream. But this will mix UI concerns into your model, so that's not acceptable for you (I'll show you how can you improve this solution to meet your expectations in a moment).
You can also create lots of ifs in form of:
if(operation is (ConcreteType))
PrintOperation((ConcreteType)operation);
This solution is ugly and error prone. Every time you add/change/remove type of operation, you have to go through every place you used these hack and modify it. And if you miss one place, you'll probably only be able to catch that runtime - no strict compile-time checks for some of errors (like missing one subtype).
Furthermore, this solution will fail as soon as you introduce any kind of proxy.
How proxy works
The code below is VERY simple proxy (in this implementation it's same as decorator pattern - but those patterns are not the same in general. It'd take some additional code to distinguish those two patterns).
public class OperationProxy : Operation
{
private readonly Operation m_innerOperation;
public OperationProxy(Operation innerOperation)
{
if (innerOperation == null)
throw new ArgumentNullException("innerOperation");
m_innerOperation = innerOperation;
}
public override double Ammount
{
get { return m_innerOperation.Ammount; }
set { m_innerOperation.Ammount = value; }
}
public override DateTime PerformedOn
{
get { return m_innerOperation.PerformedOn; }
set { m_innerOperation.PerformedOn = value; }
}
}
As you can see - there is only one proxy class for whole hierarchy. Why? Because you should write your code in a way that doesn't depend on concrete type - only on provided abstraction. This proxy could defer entity loading in time - maybe you won't use it at all? Maybe you'll use just 2 out of 1000 entities? Why load them all then?
So NHibernate uses proxy like on above (much more sophisticated, though) to defer entity loading. It could create 1 proxy per sub-type, but it would destroy whole purpose of lazy loading. If you look carefuly at how NHibernate stores subclasses you'll see, that in order to determine what type entity is, you have to load it. So it is impossible to have concrete proxies - you can only have the most abstract, OperationProxy.
Altough the solution with ifs it's ugly - it was a solution. Now, when you introduced proxies to your problem - it's no longer working. So that just leaves us with polymorphic method, which is unacceptable because of mixing UI responsibility to your model. Let's fix that.
Dependency inversion and visitor pattern
First, let's have a look at how the solution with virtual methods would look like (just added code):
public abstract class Operation
{
public abstract void PrintInformation();
}
public class OutgoingTransfer : Operation
{
public override void PrintInformation()
{
Console.WriteLine("{0}: {1}, target account: {2}",
PerformedOn, Ammount, TargetAccount);
}
}
public class AtmWithdrawal : Operation
{
public override void PrintInformation()
{
Console.WriteLine("{0}: {1}, atm's address: {2}",
PerformedOn, Ammount, AtmAddress);
}
}
public class OperationProxy : Operation
{
public override void PrintInformation()
{
m_innerOperation.PrintInformation();
}
}
And now, when you call:
Operation[] operations = { transfer, withdrawal, proxy };
foreach (var operation in operations)
{
operation.PrintInformation();
}
all works as a charm.
In order to remove this UI dependency in model, let's create an interface:
public interface IOperationVisitor
{
void Visit(AtmWithdrawal operation);
void Visit(OutgoingTransfer operation);
}
Let's modify model to depend on this interface:
And now create an implementation - ConsoleOutputOperationVisitor (I have deleted PrintInformation methods):
public abstract class Operation
{
public abstract void Accept(IOperationVisitor visitor);
}
public class OutgoingTransfer : Operation
{
public override void Accept(IOperationVisitor visitor)
{
visitor.Visit(this);
}
}
public class AtmWithdrawal : Operation
{
public override void Accept(IOperationVisitor visitor)
{
visitor.Visit(this);
}
}
public class OperationProxy : Operation
{
public override void Accept(IOperationVisitor visitor)
{
m_innerOperation.Accept(visitor);
}
}
What happens here? When you call Accept on operation and pass a visitor, implementation of accept will be called, where appropriate overload of Visit method will be invoked (compiler can determine type of "this"). So you combine "power" of virtual methods and overloads to get appropriate method called. As you can see - now UI reference here, model only depends on an interface, which can be included in model layer.
So now, to get this working, an implementation of the interface:
public class ConsoleOutputOperationVisitor : IOperationVisitor
{
#region IOperationVisitor Members
public void Visit(AtmWithdrawal operation)
{
Console.WriteLine("{0}: {1}, atm's address: {2}",
operation.PerformedOn, operation.Ammount,
operation.AtmAddress);
}
public void Visit(OutgoingTransfer operation)
{
Console.WriteLine("{0}: {1}, target account: {2}",
operation.PerformedOn, operation.Ammount,
operation.TargetAccount);
}
#endregion
}
And code:
Operation[] operations = { transfer, withdrawal, proxy };
foreach (var operation in operations)
{
operation.Accept(visitor);
}
I'm well aware that this isn't a perfect solution. You'll still have to modify the interface and visitors as you add new types. But you get compile time checking and will never miss anything. One thing that would be really hard to achieve using this method is to get pluggable subtypes - but I'm not convinced this is a valid scenario anyway. You'll also have to modify this pattern to meet your needs in concrete scenario, but I'll leave this to you.
To force a proxy to be fetched from the database, you can use the NHibernateUtil.Initialize(proxy) method, or access a method/property of the proxy.
var foo = session.Get<Foo>(id);
NHibernateUtil.Initialize(foo.Bar);
To check if an object is initialized or not, you can use the NHibernateUtil.IsInitialized(proxy) method.
Update:
To remove an object from the session cache, use the Session.Evict(obj) method.
session.Evict(myEntity);
Info about Evict and other methods for managing the session cache can be found in chapter 14.5 of the NHibernate docs.
Disabling lazy loading will force the actual instance to be returned instead of the NHibernate Proxy.
eg..
mapping.Not.LazyLoad();
or
<class name="OrderLine" table="OrderLine" lazy="false" >
Since the proxy is derived from the entity class, you can probably just check entity.GetType().BaseType to get your defined type.