A Factory for Expense Items

There are several subclasses of the class Expense in our system. In a real life application the user would select an expense type in the UI before he’d create an expense item. So the UI should provide a list of the expense types to choose from (maybe in a ComboBox); preferably the UI should not know anything about the concrete classes. After a list entry has been chosen we somehow should be able to input the choice into a black box, which creates an object of the right type. Those black boxes are called factories.

If we implement the factory class right, it is the only place in our system in which the knowledge about the available subclasses of the class Expense is stipulated. For each type there exists a description string which can be used to select the type in the UI. The factory class has a property Types which gives us a list containing all those description strings. A description string can be used as a key telling the factory, which object has to be created. (In a multi language system the string is probably a resource name string.) It is passed as a parameter to the factory method NewExpense.

Now let’s see, how the factory is implemented:

using System;

namespace BusinessClasses

{

    public class ExpenseFactory

    {

        string[] theTypes = new string[]{"Receipt", "Milage Allowance", "Per Diem Allowance"};

        public string[] Types

        {

            get { return theTypes; }

        }

        public Expense NewExpense(string type)

        {

            switch (type)

            {

                case "Receipt":

                    return new Receipt();

                    break;

                case "Milage Allowance":

                    return new MileageAllowance();

                    break;

                case "Per Diem Allowance":

                    return new PerDiemAllowance ();

                    break;

                default:

                    throw new Exception

                        (String.Format("Unknown Expense Type: {0}", type));

            }

        }

    }

}

Note that this is a very simple implementation of a factory. In real life systems we would probably use .NET Reflection to determine the available subtypes of Expense automatically. With the help of custom attributes we could specify the description strings for the subclasses:

 [NDOPersistent, DescriptionString("Per Diem Allowance")]

public class PerDiemAllowance {...}

 

It should be clear now, why the Travel class does not provide a factory method. We simply follow the design principle of separation of concerns and delegate the task of creating Expense objects to a dedicated class. So the Travel class simply has an AddExpense method.