Iteration 2: Using SRP
To preserve SRP in the client class you will create an intermediate class called Portfolio. The purpose of Portfolio will be to maintain the total values of all the clients stocks. You added a new type of associations between these classes, this is called aggregation in UML and is used in cases where one class owns another class. In Ontology
this ownership is called a part-whole relationship. Aggregation is used this way to show that a client owns a portfolio and that the portfolio contains securities.
|Figure 2. Adding a Portfolio Class: Adding a Portfolio class creates the "separation of concerns" that you are looking for. You added a type attribute to security with a default of "Stock" to allow differentiation between different types of securities. The lines with the filled in diamond represent composition, with the parent class having the diamond attached, and the child class being the other end. |
(Model Driven Architecture) the trend has been to display aggregation using regular unidirectional associations. As mentioned, from a coding perspective there is no syntactic difference. However, from a semantic view there is a difference. In the current example you know that only the client can access the portfolio. If this relationship was just an association this would not be clear. In fact, the type of aggregation used in the example is referred to as composition and only allows for single ownership.
Iteration 3: Adding Live Quotes
To value a portfolio requires some stock quotes. You could type the quotes in by hand, but in most cases the quotes are pulled in from some external system. The manner of representing aggregation has changed in the example. It has become an unfilled diamond as opposed to the filled ones in the other aggregations. This is the standard form of aggregation and is a weaker form than the composition that you used earlier. Ownership is still present but this form of aggregation allows for multiple owners. If this were represented by an association line, you would assume that the portfolio references the quotes in some fashion. By using aggregation you know that the Portfolio must be a subscriber to the quotes, not just have some relation to them. While this difference may not seem like much it will effect the supporting classes to these quotes are coded. As noted, if you auto-generated the code for this there would be no difference between associations, aggregations, and the stronger form of compositions.
|Figure 3. Adding Live Quotes to the Portfolio: Notice the use of the <<external>> stereotype for a system that exists outside of the current system.|
method of Portfolio would be changed to incorporate these quotes. You could add the following:
public double CalculateValue
for each Stock in StockCollection
double qt = Quotes.getCurrentPrice(Stock.Name);
totalValue + = (qt-Stock.Value) * Stock.Quantity;
The assumption made is that every trade conducted for the client was done at the same price. There are a couple of ways of handling this. You could use some type of averaging scheme to come up with an average stock price in Security.addTrade. Another solution would be to loop through all the trades and perform the calculation against the new quote. We can leave these details to the user.
You do have one more bit of refactoring to do. In the sample you had a variable for StockCollection. You also need to replace the Client collection that was lost when you used the Client class to represent one client.