In an earlier article ("Mastering Associations
"), patterns were mentioned in the context of design patterns. Design patterns are used at the class level for repeatable solutions to common problems including the Factory, Singleton, and Strategy patterns (as described by the GOF in their book "Design Patterns
"). As mentioned, class diagrams model classes and the associations between them and it follows that design patterns are used in the same fashion.
Architectural patterns, on the other hand, are used at the component level, relying on components and their dependencies. Examples of architectural patterns include monolithic, two-tier, three-tier, n-tier, layered, pipes and filters, hierarchical, broadcast and listeners, switchboards, and MVC. In this article I will only cover two: three-tier and MVC. (For more information on the other patterns, "UML Applied: A .NET Perspective" by Martin L. Shoemaker is a simple guide, while "Pattern-Oriented Software Architecture: A System of Patterns" by Buschman, Meunier et al. is the standard reference.)
Architectural patterns provide a method of organizing and evaluating components. In many cases the patterns are not directly visible and a couple of different architectural patterns may be tried. Each architectural pattern organizes the components in a different fashion emphasizing the architectural qualities of scalability, reusability, modifiability, and other "-ities."
In the Richmen, Inc. example I want to see if there are any problems in the architecture and whether I can solve them. I will start with the three-tier pattern and see if it answers any questions (see Figure 3).
|Figure 3. Three-Tier Pattern Applied to the Component Diagram: Each tier is represented in UML by a package: in this case Data Tier, Application Tier, and Presentation Tier. The tiers are used as holders to help organize the components.|
The three-tier pattern houses the components in three different groups or tiers named data, application, and presentation. The components in one tier are independent of the other tiers and depend only on the components in the next tier down. Advantages of this approach are that 1) the components can be modified without effecting components in the other tiers and 2) the components in the data tier can have their database connections pooled with the database-specific logic limited to only one place. The presentation tier contains the components that are necessary for viewing the application, the application tier contains the components that implement the business logic, and the data tier coordinates the connections to the databases.
In the Richmen, Inc. example the components don't follow the three-tier pattern. StockVision and PortfolioVision depend upon quote data and StockVision also depends upon the Newsfeed. This violates the rule that that the components in one tier can depend only on components in the next lower tier. If I add a new data component for PortfolioVision I would have to modify both the PortfolioVision component in the presentation tier and the Portfolio component in the application tier. If I followed the three-tier pattern then only the Portfolio component would have to be modified.
PortfolioVision shouldn't care where the data comes from. This fact is easy to see but how about the fact that both PortfolioVision and StockVision depend upon QuoteData directly? Can I add a component in the application tier to access QuoteData for these two presentation-tier components? Do I need two components? This pattern doesn't lend itself to answering these questions. Maybe another pattern would answer these questions.
The MVC Pattern
I will use another architectural pattern, the model-view-controller (MVC) pattern, to see if it can answer any architectural issues better than the three-tier pattern.
|Figure 4. MVC Pattern Applied to the Component Diagram: The containers are in different positions than in the three-tier example.|
The MVC pattern separates components into three packages: Model, View, and Controller. The model has the components that use and rely on the underlying data. The view houses the user interface components. The controller contains the components that control which view is being displayed. The model notifies the view about any changes in its data, contains the current state of the application, and responds to any queries about its current state. The view renders the model, request any updates from the model, sends any user events to the controller, and lets the controller select the different view. The controller defines the application behavior, maps the different user actions to model updates, and selects the view. (For a good discussion of the GUI implementation of Model-View-Controller look at "Enterprise Solution Patterns Using Microsoft .NET" from the Patterns and Practices series of books from Microsoft Press.)
In the Richman, Inc. example the use of MVC is easier to read. In the MVC pattern every dependency must point to the model components, which is the case in this example. QuoteData, NewsFeed, and CustomerStockData inform the StockVision and PortfolioVision components about changes in their underlying data. StockVision and PortfolioVision handle the rendering of the user interface. The only problem with StockVision and PortfolioVision is that they also operate as controllers by handling any user requests.
|Figure 5. Richman, Inc. After Refactoring Using MVC: The stock component and two- way dependencies between the controller and view components are shown. The view components pass the user actions to the controllers that notify the model to change the view.|
If it weren't for Portfolio this would be a classic Document-View architectural pattern. The controller and the view components are tightly coupled but the data components are not. The benefits of this are similar to the tier benefits. The data components, their connections, and data-access logic are separate from how the user actions are handled. The Document-View architecture was used so often is it was an implicit part of Microsoft's C++ compiler.
Should I remove the Portfolio component and move the business logic into the data and presentation tiers? If I split the logic this way, then the presentation tier would handle all of the control logic and the business logic used to transform that data into a viewable screen, and the data tier would be used to calculate aggregate values for the portfolio. The other choice would be to not use the Document-View architecture and change the Portfolio component to MVC. This would require PortfolioVision to pass any button clicks or user interface calls to Portfolio. Portfolio would react to the user interface calls informing CustomerStockData and QuoteData that there is a request to change the views. StockVision has less business logic than Portfolio and PortfolioVision but still has a dependency on QuoteData, which is now part of the MVC pattern. It would make sense to create another component called Stocks that would act in the same fashion as PortfolioVision. This would not confuse the use of QuoteData in Portfolio and StockVision.
In Figure 5 the components are refactored. From an architectural standpoint the design is stronger than before. The model data can be verified and checked without relying on the business logic in the controllers or the GUI logic in the views. Views can be added without changing the model components and the view components are not locked into the specifics of how commands are handled. If we added the command pattern to the controller even the commands could be changed dynamically. When looking at all three example diagrams it is much easier to follow the dependencies after Richman, Inc. was refactored.