As I mentioned before, Applying UML and Patterns by Craig Larman has an extensive description of GRASP, General Responsibility Assignment Software Patterns, which is a learning aid for OO design with responsibilities. There are 9 GRASP Patterns: Controller, Creator, High Cohesion, Indirection, Information Expert, Low Coupling, Polymorphism, Protected Variations, and Pure Fabrication.
I talked about the Information Expert GRASP Pattern as it relates to the Create a Shopping Cart example in the following 2 posts:
I briefly mentioned this next GRASP Pattern, Controller GRASP Pattern, when we walked through both the DotNetNuke and Community Server source code in the following 2 posts:
Let's talk about the Controller GRASP Pattern in more detail:
- Pattern Name: Controller
- Problem: What first object beyond the UI layer receives and coordinates ("controls") a system operation?
- Solution: Assign the responsibility to a class representing one of the following choices:
- Represents the overall “system,“ a “root object,“ a device that the software is running within, or a major subsystem - there are all variations of a facade controller.
- Represents a use case scenario within which the system event occurs, often named <UseCaseName>Handler, <UserCaseName>Coordinator, or <UseCaseName>Session (use case or session controller). Use the same controller class for all system events in the same use case scenario.
If you open up the CommunityServerBlogs project that is part of the Community Server source code, you will see four controller classes that are responsible for handling system operations for all UI controls that handle blog related activities:
If we re-look at the walk-thru we did of the Community Server source code, we talked about how the EntryViewContainer usercontrol used the controller class, WeblogPosts, to obtain the main post and comments for a particular BlogID and PostID to be displayed to the reader. Here is a snippet of the code showing the usercontrol and controller classes collaborating:
DotNetNuke uses a similar architecture and also spells out the controller class by ending its name with "Controller." How nice is that :) Below is a snippet of the code we discussed while digging into the DotNetNuke source code. The code shows the HtmlModule usercontrol collaborating with the HtmlTextController to get the HTML for this particular module based on its ModuleId.
On a final note, the controller class sits in the domain layer, but isn't really supposed to do much. It's job is just to hand off the request to another domain object that does the work. As you can see in the above 2 examples, WeblogPosts just quickly checks the cache and returns the PostSet if it is there or passes the request to the WeblogDataProvider. It is essentially just delegating the work. The same thing holds true for HtmlTextController. It just hands off the request to the appropriate data provider.
It's awesome to be able to see these patterns in action in both Community Server and DotNetNuke.