Selecting the Correct View for an Object Type

I've had this problem many times before, and I've never had a solution I felt good about.

Let's say I have a Transaction base class and two derived classes AdjustmentTransaction and IssueTransaction.

I have a list of transactions in the UI, and each transaction is of the concrete type AdjustmentTransaction or IssueTransaction.

When I select a transaction, and click an "Edit" button, I need to decide whether to show an AdjustmentTransactionEditorForm or an IssueTransactionEditorForm.

The question is how do I go about doing this in an OO fashion without having to use a switch statement on the type of the selected transaction? The switch statement works but feels kludgy. I feel like I should be able to somehow exploit the parallel inheritance hierarchy between Transactions and TransactionEditors.

I could have an EditorForm property on my Transaction, but that is a horrible mixing of my UI peanut butter with my Model chocolate.

Thanks in advance.

Answers


You need to map your "EditorForm" to a transaction at some point. You have a couple options:

  • A switch statement...like you, I think this stinks, and scales poorly.
  • An abstract "EditorForm" property in base Transaction class, this scales better, but has poor seperation of concerns.
  • A Type -> Form mapper in your frontend. This scales fairly well, and keeps good seperation.

In C#, I'd implement a Type -> Form mapper like this:

Dictionary <Type,Type> typeMapper = new Dictionary<Type,Type>();
typeMapper.Add(typeof(AdjustTransaction), typeof(AdjustTransactionForm));
// etc, in this example, I'm populating it by hand, 
// in real life, I'd use a key/value pair mapping config file, 
// and populate it at runtime.

then, when edit is clicked:

Type formToGet;
if (typeMapper.TryGetValue(CurrentTransaction.GetType(), out formToGet))
{
    Form newForm = (Form)Activator.CreateInstance(formToGet);
}

You probably don't want to tie it to the inheritance tree--that will bind you up pretty good later when you get a slight requirements change.

The relationship should be specified somewhere in an external file. Something that describes the relationship:

Editing AdujustmentTransaction = AdjustmentTransactionEditorForm
Editing IssueTransaction = IssueTransactionEditorForm

With a little bit of parsing and some better language than I've used here, this file could become very generalized and reusable--you could reuse forms for different objects if required, or change which form is used to edit an object without too much effort.

(You might want users named "Joe" to use "JoeIssueTransactionEditorForm" instead, this could pretty easily be worked into your "language")

This is essentially Dependency Injection--You can probably use Spring to solve the problem in more general terms.


Need Your Help

How to assign HTML content to iframe control from asp.net codebehind?

c# asp.net html

I want to assign the html content to iframe control from asp.net code behind page; this is working fine myIframe.Attributes.Add("src", "pathtofilewith.html"); but, i don't want to give the path of

Java Ant wont complete task after running a Jar

java ant junit4

I got some junit tests (in Tester App) that i want to run on a service (Service.jar running parallely). As soon as ant runs Service.jar, it wouldn't return to perform the junit test as expected bu...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.