Iteration 3: Namespaces and Refactoring
|Figure 3. Refactored Classes: The brokerage class is broken down into three classes Broker, Client and Security.|
If you look closely, there are already a couple of issues to think about. You have developed in anti-pattern parlance the "god" classone that does everything. As experienced developers, this should immediately set off some mental triggers.
If this were all in code you would be refactoring the code by now, making changes to separate out the different concerns into their classesin some cases writing new tests, putting in a new test harness and figuring out how to combine these classes together to hook back up to the GUI. This is quite a bit of work.
In this simple case, you would immediately recognize that there are some separate concerns here and develop them from the beginning as separate classes. However the temptation would be to hook every class into the GUI directly. If you were really good, you might see this problem immediately and build some type of class that would combine the three classes together, but that requires some forethought. UML provides us with an easier way to do this without the work.
In Figure 3
the brokerage class is broken down into three classes: Broker, Client and Security. You encapsulate the classes in the package Brokerage. In .NET you represent packages as namespaces. A namespace is a nice construct for separating the different concepts of an application or system. One can think of a namespace as a logical component.
public class Broker
public class Client
public class Security
|Figure 4. Class Using an Interface: An <<interface>> stereotype is the way to identify different types of classes using UML. |
If you look closely you notice that all three classes have the same operations, and more importantly, they all operate on collections. This should trip yet another alarmyou can refactor this class to reduce the duplicated logic.
From a UML standpoint this will be easier when you start adding more methods to the classes. In UML you accomplish this using the <<interface>> stereotype. A stereotype is the way to identify different types of classes using UML. They can be user defined like <<my type>> or specific to UML like <<interface>>.
The <<interface>> stereotype in BrokerageCollection accomplishes two things. Every class that uses this interface will have the exact same functionality for using collections. It also simplifies the diagram. You may wonder why the classes inherit from an interface and not another class. Inheriting from a class would have allowed me to add Brokers
, and Securities
to BrokerageCollection (interfaces don't have attributes like classes do) but .NET languages (except for C++) do not allow for multiple inheritance from classes, so the interface was used instead. If you wanted Broker to later inherit from a Person, for example, this would be impossible if BrokerageCollection
were not an interface.
public interface IBrokerageCollection
void addMember (String name);
void deleteMember (String name);
Two notes about the interface method. First, the public interface in code is IBrokerageCollection
in the model. My preference is to not use the "I" in front of the interface for modeling but if code generation is part of your modeling effort then it is a good idea to add the "I".
Second, in the example it could be argued that the System.Collections.ArrayList library class already has a method for adding, deleting, and listing members. There might, however, be other validation that is happening within the classes themselves. Specify that only strings can be added or deleted, for example. Validate on the number of characters or maybe restrict the brokers to specific identifiers rather than the names. You could also inherit three different types from System.Collections.ArrayList; BrokerCollection, ClientCollection, and SecurityCollection. In modeling, as in coding, there is often more than one solution.
I have covered how a UML class relates to code, but not yet how they relate to each other. You can easily see that it's cheaperfrom a time perspectiveto make changes in the class rather than in the code. In the next article I will cover how the classes interact. You will see how to use UML models to have the brokers sell the securities for their clients. Exciting stuff!