<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Billy McCafferty : Architecture</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx</link><description>Tags: Architecture</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Greenfield Development with ASP.NET MVC &amp; S#arp Lite - Day 3</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2012/10/16/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-3.aspx</link><pubDate>Tue, 16 Oct 2012 22:10:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70376</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;&lt;i&gt;A&amp;nbsp;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/02/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-introduction.aspx"&gt;series of posts&lt;/a&gt;&amp;nbsp;providing proven guidance for developing ASP.NET MVC applications from idea to well-designed implementation.&lt;/i&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Day 3 &amp;ndash; Define the Domain Design Model&lt;/h2&gt;
&lt;h3&gt;Objective of the Day&lt;/h3&gt;
&lt;p&gt;Transform the&amp;nbsp;actor/system interaction diagrams - from &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/24/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-1.aspx"&gt;Day 1&lt;/a&gt;&amp;nbsp;-&amp;nbsp;and the&amp;nbsp;domain conceptual model -&amp;nbsp;from&amp;nbsp;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/10/12/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-2.aspx"&gt;Day 2&lt;/a&gt;&amp;nbsp;-&amp;nbsp;into a &lt;i&gt;design&lt;/i&gt; model, which will be used as the basis for implementation. &amp;nbsp;The design model will include two artifacts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Class Diagram&lt;/strong&gt;: &amp;nbsp;A class diagram extends the domain conceptual model to include data types, methods, and supporting classes necessary for implementation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sequence Diagrams&lt;/strong&gt;: &amp;nbsp;Sequence diagrams express the interactions among classes and the messages invoking, and responding to, those interactions, accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Inputs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Actor/System interaction diagrams&lt;/li&gt;
&lt;li&gt;Domain conceptual model&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Activities&lt;/h3&gt;
&lt;p&gt;Designing the domain &lt;i&gt;conceptual&lt;/i&gt; model, and evolving that into the domain &lt;i&gt;design&lt;/i&gt; model represents the transition from business-oriented to implementation-oriented requirements. &amp;nbsp;While there are two outputs from this process, class diagrams and sequence diagrams, they are defined in parallel with each other, each contributing to the design of the other.&lt;/p&gt;
&lt;p&gt;Transforming the conceptual model into a design model is most effectively done iteratively. &amp;nbsp;This does not mean that each refinement need take a two-week iteration to complete. &amp;nbsp;Indeed, each iterative refinement may only take 30 minutes or so to complete. &amp;nbsp;Tackling this transformation iteratively allows you to learn from each pass, applying new knowledge to the class diagram and to the sequence diagrams in successive passes.&lt;/p&gt;
&lt;p&gt;Furthermore, you need not tackle the entire domain model when defining the design model; only focus on the scope and level of detail that is immediately useful.&lt;/p&gt;
&lt;p&gt;The steps involved with each elaboration iteration, for defining/refining the class diagram and sequence diagrams, are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify the bounded context which will be the focus of design model elaboration. &amp;nbsp;(The bounded context need not be strictly adhered to, but should be identified to assist in focusing the elaboration effort.)&lt;/li&gt;
&lt;li&gt;Select one or more high priority User Stories (or Use Cases) which are representative of the bounded context and, preferably, are of higher risk.&lt;/li&gt;
&lt;li&gt;Refine (or initially define) the class diagram, focusing on classes, attributes, and associations within the context of the User Stories.&lt;/li&gt;
&lt;li&gt;For each User Story, refine (or initially define) sequence diagrams illustrating the behavior and interactions of each class involved.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Update the class diagram to reflect any new or modified classes, behaviors, and/or attributes discovered during the design of sequence diagrams.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When defining sequence diagrams, do not feel constrained to only include classes which are already defined within the class diagram. &amp;nbsp;The exercise of building out the sequence diagrams will quickly lead to the discovery of new classes and behaviors which are not yet a part of the class diagram; that&amp;rsquo;s one of the points of doing this. &amp;nbsp;Furthermore, &lt;i&gt;do not&lt;/i&gt; feel obliged to create a sequence diagram for every User Story or requirement. &amp;nbsp;Sequence diagrams are time consuming to create and are quickly subject to change. &amp;nbsp;Accordingly, I see sequence diagrams as disposable artifacts which need not be maintained after they have been implemented as code.&lt;/p&gt;
&lt;p&gt;Sequence diagrams are particularly useful at the following times:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To illustrate the interactions involved with a complex User Story,&lt;/li&gt;
&lt;li&gt;To illustrate a &amp;quot;boiler-plate activity,&amp;quot; such as the interactions involved with the CRUD (create/read/update/delete) of a single domain object, in order to establish a standard practice and to serve as a useful reference for new team members, and&lt;/li&gt;
&lt;li&gt;To tell a more junior developer &lt;i&gt;exactly&lt;/i&gt; how you&amp;rsquo;d like something implemented.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the final step, when updating the class diagram to reflect new or modified behaviors, use each message, passed between two classes within the sequence diagram, to indicate the need for a respective method on the class from which the message originates. &amp;nbsp;In other words, if a communication is indicated between two classes in the sequence diagram, there should be a respective method (or return result from a message) in the class diagram.&lt;/p&gt;
&lt;p&gt;Deciding to what granularity to create the sequence diagrams is a tricky decision. &amp;nbsp;If too little time is spent, then the sequence diagram will provide very little guidance towards implementation. &amp;nbsp;But too much time may result in granularity which is otherwise obvious or clearly assumed. &amp;nbsp;As a rule, continue to break-down the sequence diagram to further levels of granularity until:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The effort is no longer reducing uncertainty and risk,&lt;/li&gt;
&lt;li&gt;The increased granularity is no longer providing &amp;quot;new&amp;quot; information, or&lt;/li&gt;
&lt;li&gt;The increased granularity is no longer useful to the task at hand (such as providing an initial estimate).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From the perspective of including this practice within an overall project methodology, defining/refining the design model should be roughly performed at the beginning of a project to assist with estimating and to improve understanding of the project. &amp;nbsp;It should also be performed in more detail at the beginning of each development iteration to define/refine the design model for that iteration.&lt;/p&gt;
&lt;h4&gt;GRASP Patterns&lt;/h4&gt;
&lt;p&gt;The definitive challenge at this point is figuring out exactly how to transform the conceptual domain model into an appropriate design model describing classes with attributes, associations, and behavior. &amp;nbsp;While sequence diagrams are a tool to visualize interactions among classes and their behaviors, the diagramming technique itself does not provide guidance on &lt;i&gt;how&lt;/i&gt; to determine how the classes will interact and what their respective behaviors will be. &amp;nbsp;Doing this correctly is a critical element to ensuring the codebase is well-designed and maintainable.&lt;/p&gt;
&lt;p&gt;GRASP patterns provide guidance for assigning responsibility and interactions to objects; GRASP is an acronym for General Responsibility Assignment Software Patterns and were defined to provide guidance for OOA&amp;amp;D. &amp;nbsp;While there are nine GRASP patterns in all, five key GRASP patterns should be mastered and considered continuously in the creation of the design model. &amp;nbsp;What follows are the five patterns, each including the problem that arises when adding behavior to a model, and the guiding principle/solution for meeting that challenge. &amp;nbsp;(Reference &lt;a href="http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062"&gt;Applying UML and Patterns&lt;/a&gt; by Craig Larman, from which the following patterns are quoted, for a very well written discussion of these principles and other fundamentals of OOA&amp;amp;D.)&lt;/p&gt;
&lt;p&gt;&lt;i style="font-weight:bold;"&gt;Information Expert&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Problem&lt;/i&gt;: &amp;nbsp;What is a general principle of assigning responsibilities to objects?&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Solution&lt;/i&gt;: &amp;nbsp;Assign a responsibility to the information expert - the class that has the &lt;i&gt;information&lt;/i&gt; necessary to fulfill the responsibility.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Creator&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Problem&lt;/i&gt;: &amp;nbsp;Who should be responsible for creating a new instance of some class?&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Solution&lt;/i&gt;: &amp;nbsp;Assign class B the responsibility to create an instance of class A if one or more the following is true:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;B &lt;i&gt;aggregates&lt;/i&gt; A objects.&lt;/li&gt;
&lt;li&gt;B &lt;i&gt;contains&lt;/i&gt; A objects.&lt;/li&gt;
&lt;li&gt;B &lt;i&gt;records&lt;/i&gt; instances of A objects.&lt;/li&gt;
&lt;li&gt;B &lt;i&gt;closely uses&lt;/i&gt; A objects.&lt;/li&gt;
&lt;li&gt;B has the &lt;i&gt;initializing&lt;/i&gt; data that will be passed to A when it is created (thus B is an Information Export with respect to creating A).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An exception to this is that if the logic required to create class A is of considerable complexity, consider moving the creation logic to a helper class, called a Factory [&lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612"&gt;GoF 1995&lt;/a&gt;].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Low Coupling&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Problem&lt;/i&gt;: &amp;nbsp;How to support low dependency, low change impact, and increased reuse? &amp;nbsp;Coupling is how strongly one class is connected to, or has knowledge of, other classes. &amp;nbsp;Highly coupled classes suffer from the following problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Changes in related classes force local changes.&lt;/li&gt;
&lt;li&gt;Harder to understand in isolation.&lt;/li&gt;
&lt;li&gt;Harder to reuse because its use requires the additional presence of the classes on which it is dependent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;i&gt;Solution&lt;/i&gt;: &amp;nbsp;Assign a responsibility so that coupling remains low.&lt;/p&gt;
&lt;p&gt;This terse solution is not very helpful; indeed, it&amp;rsquo;s often simpler to instill low coupling by watching for signs of tight coupling and to refactor, accordingly. &amp;nbsp;Martin Fowler&amp;rsquo;s &lt;a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672"&gt;Refactoring&lt;/a&gt; is by far the best resource available for becoming familiar with these &amp;quot;smells&amp;quot; along with concrete guidance for taking corrective action.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;High Cohesion&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Problem&lt;/i&gt;: &amp;nbsp;How to keep complexity manageable? &amp;nbsp;Cohesion is how strongly related the responsibilities of a class are. &amp;nbsp;Classes with low cohesion suffer from the following problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hard to comprehend.&lt;/li&gt;
&lt;li&gt;Hard to reuse.&lt;/li&gt;
&lt;li&gt;Hard to maintain.&lt;/li&gt;
&lt;li&gt;Delicate and constantly effected by change.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;i&gt;Solution&lt;/i&gt;: &amp;nbsp;Assign a responsibility so that cohesion remains high.&lt;/p&gt;
&lt;p&gt;Like the solution for Low Coupling, this isn&amp;rsquo;t immediately useful advice. &amp;nbsp;The point is to aim towards encapsulating related logic together, and to introduce new classes as necessary to continue to do so. &amp;nbsp;Again, &lt;a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672"&gt;Fowler&amp;#39;s Refactoring&lt;/a&gt;&amp;nbsp;is a tremendous resource for this topic.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;strong&gt;Controller&lt;/strong&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Problem&lt;/i&gt;: &amp;nbsp;Who should be responsible for handling an input system event?&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Solution&lt;/i&gt;: &amp;nbsp;Assign the responsibility for receiving or handling a system event message to a class representing one of the following choices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Represents the overall system as a Facade [&lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612"&gt;GoF 1995&lt;/a&gt;].&lt;/li&gt;
&lt;li&gt;Represents a User Story or Use Case scenario within which the system event occurs, often named &amp;lt;UserStoryName&amp;gt;Handler, &amp;lt;UserStoryName&amp;gt;Coordinator, or &amp;lt;UserStoryName&amp;gt;Controller.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As an aside, this GRASP pattern is nicely enabled via ASP.NET MVC with an explicit controller layer. &amp;nbsp;But as the naming of a controller would imply, the scope of each controller should be limited to that implied by its name, accordingly. &amp;nbsp;For example, a controller by the name of &amp;quot;ManageUsersController&amp;quot; would imply performing User-related CRUD operations; User-related report generation should likely belong to a separate controller. &amp;nbsp;Incidentally, this would also better support High Cohesion - what is good for the support of one pattern is often good for another.&lt;/p&gt;
&lt;h4&gt;CRC Cards&lt;/h4&gt;
&lt;p&gt;It is sometimes difficult to figure out the very first step for adding behavior and collaboration activities to objects. &amp;nbsp;A technique which may assist with getting the ball rolling or to help when brainstorming the behavior of a new bounded context within a domain is a technique known as CRC cards &amp;nbsp;(Class-Responsibility-Collaborator cards).&lt;/p&gt;
&lt;p&gt;CRC cards are very simple yet effective for defining brainstorming the responsibilities of each object. &amp;nbsp;To utilize, grab some index cards, title each with a class name of interest, and write two things on each:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Responsibilities&lt;/strong&gt;: &amp;nbsp;For each CRC card (i.e., each class), write one or a few bullet points describing the extent of responsibility for the class. &amp;nbsp;Keep GRASP patterns in mind when defining the scope of responsibility.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Collaborator Objects&lt;/strong&gt;: &amp;nbsp;List one or more collaborator classes which need to be interacted with in order to carry out the responsibilities of that class.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;After documenting responsibilities and identifying collaborator objects, the task of transforming this information into the class diagram, and into sequence diagrams, is greatly simplified.&lt;/p&gt;
&lt;h4&gt;Refactoring &amp;amp; Refactoring to Patterns&lt;/h4&gt;
&lt;p&gt;GRASP patterns are a tremendous guide for answering the question of &amp;quot;what belongs where.&amp;quot; &amp;nbsp;But as a system evolves, changes are inevitably introduced by client request, or more frequently, by further discovery of requirements. &amp;nbsp;For example, what may at first appear to be simple may quickly become complex after coding begins. &amp;nbsp;In these cases, refactoring techniques can greatly assist to answer the question of &amp;quot;how to adapt to change.&amp;quot; In a nutshell, refactoring is the practice of improving the design of existing code. &amp;nbsp;While the details of refactoring are beyond the scope of this article, two tremendous resources (i.e., absolutely required reading for any developer) are &lt;a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672"&gt;Refactoring&lt;/a&gt; by Martin Fowler and &lt;a href="http://www.amazon.com/Refactoring-Patterns-Joshua-Kerievsky/dp/0321213351"&gt;Refactoring to Patterns&lt;/a&gt; by Joshua Kerievsky.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Putting it Into Practice&lt;/h4&gt;
&lt;p&gt;This day&amp;rsquo;s &amp;quot;Putting it Into Practice&amp;quot; will consist of a number of example artifacts, including the class diagram (both&amp;nbsp;initial and revised), CRC cards, and sequence diagrams. &amp;nbsp;Let&amp;rsquo;s review each in turn.&lt;/p&gt;
&lt;p&gt;By far, transforming the concept model into the design model is the one of the trickiest tasks and the most important to get as close to &amp;quot;right&amp;quot; as possible. &amp;nbsp;The rule to keep in mind is to design the simplest model which could possibly work to fit the needs of the requirements and elaborate iteratively and only when necessary. &amp;nbsp;(Keeping in mind the design elaboration steps discussed previously.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Initial Domain Class Diagram&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At some point, the concept model must be transformed into an implementable design model. &amp;nbsp;This is the time to put our techie hats on and start to think in terms of classes, properties and methods. &amp;nbsp;To get the ball rolling, let&amp;rsquo;s take a stab at designing a minimal class diagram to support the concept model discussed earlier.&lt;/p&gt;
&lt;p&gt;Initially, we&amp;rsquo;ll focus on the bounded context of support ticket management, and the objects which participate with this activity. &amp;nbsp;We&amp;rsquo;ll leave the reporting context until later on; this will also give Acme Telecom a little more time to make up their mind on what they want to see in the report.&lt;/p&gt;
&lt;p&gt;What follows is the class diagram reflecting the first attempt at modeling the domain as an implementable design:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/InitialClassDiagram.png"&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/InitialClassDiagram.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are a number of differences from the conceptual model which were carefully considered:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The concepts Management, SupportStaff, and Admin have been combined into a single class called StaffMember. &amp;nbsp;The following considerations were taken into account to make this decision:
&lt;ul&gt;
&lt;li&gt;All of these concept objects are employees of Acme Telecom.&lt;/li&gt;
&lt;li&gt;Each of the concepts share duplicate data.&lt;/li&gt;
&lt;li&gt;While each may be allowed to do different tasks (e.g., manage staff vs. open support tickets), it does not yet appear that the classes themselves would behave differently. &amp;nbsp;I.e., it&amp;rsquo;s not yet apparent that an Admin class would have different methods than a Manager class.&lt;/li&gt;
&lt;li&gt;Having the flags &amp;quot;IsAdmin&amp;quot;&amp;nbsp;and&amp;nbsp;&amp;quot;IsManager&amp;quot;&amp;nbsp;may indicate that we may need role-management capabilities; while this may be true, we&amp;rsquo;ll want to avoid delving into the weeds further until warranted. &amp;nbsp;(With that said, we&amp;rsquo;ll want to fully think out security management before we begin coding&amp;hellip;it&amp;rsquo;s much more difficult to incorporate security management later on in project development.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The concepts SupportTicket and SupportCall have been merged into a single class called SupportTicket. &amp;nbsp;This could have been argued either way, but the two concepts are equivalent from a data workflow perspective. &amp;nbsp;Consequently, I went for the simpler approach.&lt;/li&gt;
&lt;li&gt;SupportTicket.Status has been pulled out as an enum value as we rarely expect the status types to change. &amp;nbsp;Additionally, since the status may also be considered within data workflows, having it as an enum value will simplify the workflow conditionals and provide support for the use of a finite state machine, if deemed necessary down the road. &amp;nbsp;(See&amp;nbsp;Kerievsky&amp;#39;s&amp;nbsp;&lt;a href="http://www.amazon.com/Refactoring-Patterns-Joshua-Kerievsky/dp/0321213351"&gt;Refactoring to Patterns&lt;/a&gt; for guidance on when/how to make this decision.)&lt;/li&gt;
&lt;li&gt;Preferably, SupportTicket.IssueType would also be an enum to keep things simple. &amp;nbsp;But, the requirements state that the SupportStaff must be able to dynamically add new issue types, when needed, when opening a support ticket. &amp;nbsp;Consequently, IssueType will need to be a persistable domain class.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take special note that this model does not imply anything about infrastructural details such as persistence and security. &amp;nbsp;These will be added to the class diagram as they are included in the sequence diagrams. &amp;nbsp;Trying to anticipate all of the infrastructural classes at this time will likely lead to over-engineering (or &lt;i&gt;wrong&lt;/i&gt;-engineering altogether).&lt;/p&gt;
&lt;p class="MsoNormal"&gt;With that said, the architect should have a good idea of how such infrastructural concerns will be addressed in the final solution. &amp;nbsp;It is appropriate to have at least discussed how the overall project will be architected and what tools will be used to support infrastructural concerns. &amp;nbsp;The overall architecture will have a strong impact on the sequencing of messages through the application tiers.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;For the task at hand, we&amp;rsquo;ll take into account the fact that we&amp;rsquo;ll be using S#arp Lite as our underlying framework and architecture.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i&gt;Accordingly, &lt;strong&gt;before going further&lt;/strong&gt;, read the article &amp;quot;S#arp Lite: &amp;nbsp;The Basics&amp;quot; to get a better understanding of how a S#arp Lite project is architected: &amp;nbsp;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2011/11/11/s-arp-lite-the-basicss.aspx"&gt;http://devlicio.us/blogs/billy_mccafferty/archive/2011/11/11/s-arp-lite-the-basicss.aspx&lt;/a&gt;&amp;nbsp;. &amp;nbsp;Pay particular attention to the package diagram, describing how the layers are organized.&lt;/i&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong&gt;&lt;i&gt;Sequence Diagram for Opening a New Support Ticket&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Did you read the introduction to S#arp Lite as referenced above? &amp;nbsp;OK, great, we&amp;rsquo;re ready to continue. &amp;nbsp;(You&amp;#39;ll likely be lost, bewildered, confuddled and worse if you haven&amp;#39;t read it...I hope you&amp;#39;ll only experience one or two of those symptoms if you &lt;i&gt;have&lt;/i&gt;&amp;nbsp;read it.)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;We have designed the beginnings of the class diagram. &amp;nbsp;We&amp;rsquo;re now ready to elaborating, refining, and adding behavior to the class diagram by analyzing the sequence of events involved with opening a new support ticket. &amp;nbsp;This particular user story was selected because it covers much of the bounded context that we&amp;rsquo;re currently working on and is a critical element of the CLogS application.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;As we&amp;rsquo;ll see, the design of the sequence diagram is where we have to seriously start thinking about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How will data be loaded from the database?&lt;/li&gt;
&lt;li&gt;How will data be saved to the database?&lt;/li&gt;
&lt;li&gt;How will messages travel among the Web, Controllers, Tasks, Domain, and Data layers of the project?&lt;/li&gt;
&lt;li&gt;How will the Tasks layer expose the core API of the application to the Controllers layer?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While this is a daunting task, be patient and revise your first sequence diagram many times until you feel it&amp;rsquo;s clear and clean.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Let&amp;rsquo;s now consider a sequence diagram for the following user story:&lt;/p&gt;
&lt;p class="MsoNormal" style="padding-left:30px;"&gt;&lt;i&gt;Support Staff may open a new support ticket and provide details including: &amp;nbsp;Customer, Issue Details (such as description and &amp;quot;dynamically managed&amp;quot; type), Status, and Resolution Details (if resolved immediately). &amp;nbsp;Status of the call may be New, In Progress, or Resolved. &amp;nbsp; (&amp;quot;Dynamically managed&amp;quot; means that if the issue type isn&amp;rsquo;t available, the Support Staff may enter a new one when entering the support ticket.)&lt;/i&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;To make things simpler, ignore any extraneous features in the first design of the sequence diagram to focus on the core of the requirements; e.g., we&amp;rsquo;ll ignore the dynamically managed issue types for now.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/NewSupportTicketSequenceDiagram.png"&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/NewSupportTicketSequenceDiagram.png" alt="" /&gt;&lt;br /&gt;&lt;/a&gt;(Click to embiggen.)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;The sequence diagram above describes the collaboration of objects in support of allowing a staff member to open a new support ticket.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;While designing the above sequence diagram, four new objects were identified, which may be added to the class diagram:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ManageSupportTicketController&lt;/strong&gt;: &amp;nbsp;This MVC controller class will reside in the .Web layer of the project and will have the responsibility of handling requests for the management of a support ticket.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ManageSupportTicketTasks&lt;/strong&gt;: &amp;nbsp;This tasks class (aka &amp;quot;application service&amp;quot; class [&lt;a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420"&gt;Fowler 2002&lt;/a&gt;]) &amp;nbsp;will reside in the .Tasks layer of the project and will have the responsibility of carrying out the coordination activities for the management of a support ticket.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SupportTicketViewModel&lt;/strong&gt;: &amp;nbsp;This view model DTO (data-transfer object) will carry information from the controller to the view and vice-versa for the purposes of allowing a StaffMember to add/update support ticket information.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IRepository&amp;lt;SupportTicket&amp;gt;&lt;/strong&gt;: &amp;nbsp;This interface will provide a means to communicate with the underlying data access mechanism to persist the new support ticket to the database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;In a nutshell, the sequence is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The StaffMember requests to open a new support ticket.&lt;/li&gt;
&lt;li&gt;The StaffMember is presented with a form.&lt;/li&gt;
&lt;li&gt;A sub-process facilitates the StaffMember to select the respective customer (elaborated below).&lt;/li&gt;
&lt;li&gt;The StaffMember provides the requested information and submits the form.&lt;/li&gt;
&lt;li&gt;The StaffMember is either:
&lt;ul&gt;
&lt;li&gt;presented with the same form, with validation information, if the submitted information contained validation problems, or&lt;/li&gt;
&lt;li&gt;presented with a listing of open support tickets with a message stating that the support ticket was successfully saved.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We&amp;rsquo;ll now turn our attention to look at the sub-process for selecting a customer...&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/SelectCustomerSequenceDiagram.png"&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/SelectCustomerSequenceDiagram.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The sequence diagram above describes the sequence of events to allow a StaffMember to select a customer via an AJAX post-back on the page. &amp;nbsp;The form will have a &amp;quot;Customer Account Number&amp;quot; input box on it; when it changes, an AJAX post-back will try to find the customer record. &amp;nbsp;If the customer exists, the customer information will be dynamically shown; if it doesn&amp;rsquo;t, the StaffMember will need to provide a few customer details before submitting the form.&lt;/p&gt;
&lt;p&gt;As implied, many details about a user story are discovered during the process of designing a sequence diagram. &amp;nbsp;To ease organization of the requirements, the sequence diagrams and details may be simply printed out and stapled to an index card with the user story written on it, or uploaded as attachments to the user story in an online requirements management tool.&lt;/p&gt;
&lt;p&gt;In both sequence diagrams, arguments may be made that all of the UML is not &amp;quot;by the book&amp;quot;; e.g., the use of stereotypes has been basterdized a bit to make the diagram more expressive. &amp;nbsp;I bring this up to express the point that less time should be spent worrying about making a UML diagram perfect as should be spent conveying useful information. &amp;nbsp;When everything&amp;rsquo;s said and done, these diagrams will likely be thrown away once they&amp;rsquo;ve been implemented as working code.&lt;/p&gt;
&lt;p&gt;If the underlying project architecture is already established (e.g., we&amp;rsquo;re using S#arp Lite as the foundation), designing the sequence diagram is relatively straight-forward. &amp;nbsp;If the intention is to grow the architecture &amp;quot;organically,&amp;quot; then elaborating the sequence diagram may take a few iterations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;CRC Cards for &amp;quot;Ticket Resolution Report by Support Staff&amp;quot;&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In our discussions thus far, we haven&amp;rsquo;t gotten into the details of exactly how the support ticket resolution report will be generated. &amp;nbsp;So before tackling the respective sequence diagram, we&amp;rsquo;ll use CRC cards to brainstorm a bit about the classes to be involved with the user story. &amp;nbsp;The CRC cards don&amp;rsquo;t need to be exhaustively detailed; just enough in order to move on to the associated sequence diagram. &amp;nbsp;CRC cards don&amp;rsquo;t/shouldn&amp;rsquo;t need to be maintained throughout the project life-cycle; once they&amp;rsquo;ve served their usefulness, toss them (or archive them away to some hidden place if throwing them away saddens you).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/CrcCardsForReports.png"&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/CrcCardsForReports.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As demonstrated, the CRC cards were used to work out the basics of the classes involved with generating a support ticket resolution report, per the requirements. &amp;nbsp;Now that the general responsibilities have been defined, we&amp;rsquo;re able to confidently move on to designing the respective sequence diagram.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Sequence Diagram for Creating a &amp;quot;Ticket Resolution Report by Support Staff&amp;quot;&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/TicketResolutionReportSequenceDiagram.png"&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/TicketResolutionReportSequenceDiagram.png" alt="" /&gt;&lt;br /&gt;&lt;/a&gt;(Click to invigorate.)&lt;/p&gt;
&lt;p&gt;The sequence diagram above describes the collaboration of objects in support of the creation of a support ticket resolution report for a specific staff member.&lt;/p&gt;
&lt;p&gt;While designing the above sequence diagram, four new objects were identified, which may be added to the class diagram:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SupportTicketReportsController&lt;/strong&gt;: &amp;nbsp;This MVC controller class will reside in the .Web layer of the project and will have the responsibility of handling requests for the creation of support ticket related reports.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SupportTicketReportTasks&lt;/strong&gt;: &amp;nbsp;This tasks class will reside in the .Tasks layer of the project and will have the responsibility of carrying out the coordination activities for the creation of support ticket related reports.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IRepository&amp;lt;StaffMember&amp;gt;&lt;/strong&gt;: &amp;nbsp;This interface will provide a means to communicate with the underlying data access mechanism to retrieve staff member information.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IRepository&amp;lt;SupportTicket&amp;gt;&lt;/strong&gt;: &amp;nbsp;This interface will provide a means to communicate with the underlying data access mechanism to retrieve support ticket information.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;rsquo;ll now turn our attention to look at the revised domain class diagram, taking into account what we&amp;rsquo;ve learned with the creation of the CRC cards and sequence diagrams.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Revised Domain Class Diagram&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/RevisedPackageAndClassDiagram.png"&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/RevisedPackageAndClassDiagram.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now it&amp;rsquo;s starting to look like a real application! &amp;nbsp;(On paper anyway. &amp;gt;:/ ) &amp;nbsp;The class diagram now contains enough classes to warrant noting which project layer each class belongs in. &amp;nbsp;We also have enough information to decorate classes with methods (i.e., behavior) in addition to attributes. &amp;nbsp;If you&amp;rsquo;ve been paying attention, you may notice that some of the class names are slightly different from the CRC cards and/or sequence diagrams; e.g., ManageCustomersController was called ManageCustomerController in the sequence diagram. &amp;nbsp;This is perfectly fine and expected; your design should continue to evolve as conventions are established, details are discovered, and new changes are incorporated.&lt;/p&gt;
&lt;p&gt;With the sequence diagrams established to describe how the objects collaborate, and the class diagram designed to show how the classes are organized, we&amp;rsquo;re ready to begin switching gears from design to implementation. &amp;nbsp;If you&amp;rsquo;ve been designing user stories along the way, the actual implementation should be the easy part!&lt;/p&gt;
&lt;h3&gt;Outputs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Domain class diagram&lt;/li&gt;
&lt;li&gt;Sequence diagrams&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That wraps up Day 3 in this series. &amp;nbsp;In Day 4, we&amp;#39;ll begin the implementation phase of the project and get our hands dirty with some code!&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;br /&gt;Billy McCafferty&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70376" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Lite/default.aspx">S#arp Lite</category></item><item><title>Greenfield Development with ASP.NET MVC &amp; S#arp Lite - Day 2</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2012/10/12/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-2.aspx</link><pubDate>Fri, 12 Oct 2012 22:00:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70370</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;i&gt;A&amp;nbsp;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/02/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-introduction.aspx"&gt;series of posts&lt;/a&gt;&amp;nbsp;providing proven guidance for developing ASP.NET MVC applications from idea to well-designed implementation.&lt;/i&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Day 2 &amp;ndash; Define the Domain Conceptual Model&lt;/h2&gt;
&lt;h3&gt;Objective of the Day&lt;/h3&gt;
&lt;p&gt;Transform the requirements from &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/24/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-1.aspx"&gt;Day 1&lt;/a&gt; into an appropriate domain conceptual model reflecting objects, attributes, and associations.&lt;/p&gt;
&lt;h3&gt;Inputs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Project Vision&lt;/li&gt;
&lt;li&gt;User Stories or Use Cases&lt;/li&gt;
&lt;li&gt;Data Dictionary&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Activities&lt;/h3&gt;
&lt;p&gt;The domain &lt;i&gt;conceptual&lt;/i&gt; model is a visual representation of conceptual or real-world objects in the domain of interest [&lt;a href="http://www.amazon.com/Analysis-Patterns-Reusable-Object-Models/dp/0201895420"&gt;Fowler, 1996&lt;/a&gt;]. &amp;nbsp;(The domain &lt;i&gt;design &lt;/i&gt;model, which will be discussed in Day 3, is a visual representation of the classes and behaviors which will be implemented in the software.)&lt;/p&gt;
&lt;p&gt;The conceptual model is &lt;i&gt;not &lt;/i&gt;a class diagram describing classes with methods. &amp;nbsp;But in practice, the conceptual model will iteratively &lt;i&gt;become&lt;/i&gt; the basis of the class diagram of the design model. &amp;nbsp;Specifically, the conceptual model reflects the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Domain conceptual objects,&lt;/li&gt;
&lt;li&gt;Associations between conceptual objects, and&lt;/li&gt;
&lt;li&gt;Attributes of conceptual objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The important distinction between conceptual model and design model is that the conceptual model should represent a clear business-oriented abstraction of the domain; i.e., the client should be able to look at the conceptual model and understand it fully without difficulty. &amp;nbsp;Compare this to the design model which will include method names, data types, polymorphic associations, and supporting classes, such as factories and services.&lt;/p&gt;
&lt;p&gt;To illustrate, suppose your domain includes the concept of &amp;ldquo;Customer&amp;rdquo; and &amp;ldquo;Employee.&amp;rdquo; &amp;nbsp;The conceptual model would reflect two separate objects, each having duplicate attributes such as first name and last name. &amp;nbsp;The design model may instead reflect a parent &amp;ldquo;Person&amp;rdquo; class, inherited by both Customer and Employee, having duplicated fields moved up to the Person superclass. &amp;nbsp;&lt;a href="http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062"&gt;Applying UML and Patterns [Larman 2004]&lt;/a&gt;&amp;nbsp;goes into great deal concerning this process and is highly recommended read.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll get into more details of the design process when we see it in action, next.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Putting it Into Practice&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For Acme Telecom&amp;rsquo;s CLogS, the business requirements have been established. &amp;nbsp;It is now time to begin transforming the requirements into a domain model.&lt;/p&gt;
&lt;p&gt;The first step along this path is to define the conceptual model. &amp;nbsp;We&amp;rsquo;ll define the conceptual objects, define their relationships with other objects, and add attributes, describing the pertinent information associated with each. &amp;nbsp;But how exactly do we go about naming the conceptual objects? &amp;nbsp;[&lt;a href="http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062"&gt;Larman 2004&lt;/a&gt;] suggests looking for objects which fall into a Conceptual Class Category, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Physical or tangible objects,&lt;/li&gt;
&lt;li&gt;Places,&lt;/li&gt;
&lt;li&gt;Transactions and transaction line items,&lt;/li&gt;
&lt;li&gt;Roles of people,&lt;/li&gt;
&lt;li&gt;Physical container of other things,&lt;/li&gt;
&lt;li&gt;Things in a container,&lt;/li&gt;
&lt;li&gt;Organizations,&lt;/li&gt;
&lt;li&gt;Events,&lt;/li&gt;
&lt;li&gt;Processes,&lt;/li&gt;
&lt;li&gt;Rules and policies, or&lt;/li&gt;
&lt;li&gt;Nouns.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For finding associations, Larman suggests looking for the following types of associations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A is a physical or logical part of B,&lt;/li&gt;
&lt;li&gt;A is physically or logically contained in/on B, or&lt;/li&gt;
&lt;li&gt;A is recorded in or is a line item of B.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that we know what to look for, what artifacts do we look at as potential sources for objects? &amp;nbsp;The primary sources include the vision, data dictionary, and user stories; i.e., the artifacts from &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/24/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-1.aspx"&gt;Day 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As a caveat, if you find conceptual objects in the vision or data dictionary that are &lt;i&gt;not&lt;/i&gt; included in the user stories, you should double check to make sure that the user stories are adequately representative of the requirements. &amp;nbsp;While you may find extra concepts in the data dictionary, since it provides explanatory details of terms, extra concepts in the vision &amp;ndash; but not found in the user stories &amp;ndash; likely indicates an inadequacy, accordingly.&lt;/p&gt;
&lt;p&gt;Looking at the inputs from the previous day, potential conceptual objects include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Customer&lt;/li&gt;
&lt;li&gt;Support Staff&lt;/li&gt;
&lt;li&gt;Management&lt;/li&gt;
&lt;li&gt;Support Call&lt;/li&gt;
&lt;li&gt;Support Ticket&lt;/li&gt;
&lt;li&gt;Ticket Resolution Report per Support Staff&lt;/li&gt;
&lt;li&gt;Ticket Resolution Report per Issue Type&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Compiling the list of concept objects will likely incite useful discussion, much of which will help to ensure that the business has been adequately modeled, and how the concept model will be later transformed into the design model.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/ConceptualDomainModel.png"&gt;&lt;img style="border:0;float:right;margin:3px;" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/ConceptualDomainModel.png" border="0" alt="" /&gt;&lt;/a&gt;At right, review an example of how the conceptual model could be visually modeled, for the concepts discussed, with associations and attributes. &amp;nbsp;As shown, all of the major elements of the conceptual model have been visualized. &amp;nbsp;There are some interesting things to note concerning this model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are many duplicated fields between Management and SupportStaff. &amp;nbsp;When implemented, these will likely be combined into a single Employee class; but recall that this is the &lt;i&gt;conceptual&lt;/i&gt; model and should include more, rather than less, detail to cover all of the unique concepts within the requirements.&lt;/li&gt;
&lt;li&gt;SupportTicket and SupportCall have a one-to-one relationship with each other. &amp;nbsp;These may have instead been merged into a single concept (and will be done so in the design model), but splitting them into separate concepts at this stage emphasizes that there is a call from the customer which leads to a ticket being opened.&lt;/li&gt;
&lt;li&gt;TicketResolutionReport is a report concept which includes a listing of SupportTickets and a number of ResolutionMetrics. &amp;nbsp;Note that there is not an explicit association between TicketResolutionReport and the SupportTicket object to emphasize that the report, rather than being a core element of the domain, is an auxiliary concept to the domain. &amp;nbsp;This is a subtle and subjective point but can help to establish &lt;a href="http://devlicious.com/blogs/casey/archive/2009/02/11/ddd-bounded-contexts.aspx"&gt;bounded contexts&lt;/a&gt; &amp;nbsp;during the design of the implementation. &amp;nbsp;While it would not have been wrong to have included an explicit association, doing so would not have added much useful meaning to the context of the requirements. &amp;nbsp;Associations between objects in a conceptual model should indicate some degree of permanence.&lt;/li&gt;
&lt;li&gt;As an additional note, the ResolutionMetrics attribute of TicketResolutionReport may indeed be a separate concept object itself; but at this point, it&amp;rsquo;s added as a placeholder, to be expanded upon at a later time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As may be inferred, there&amp;rsquo;s certainly a lot of subjectivity and brainstorming that goes into creating the domain conceptual model. &amp;nbsp;As such, don&amp;rsquo;t try as much to get it &amp;quot;just right&amp;quot; as to ensure that it comprehensively captures all of the key concepts and associations within the requirements.&lt;/p&gt;
&lt;p&gt;When creating the conceptual model and you are faced with the decision to split a concept (or merge separate concepts), err on the side of splitting the concept to provide more granularity than may be necessary for the actual implementation; i.e., it&amp;rsquo;s better for the conceptual model to be too expressive than too simplistic. &amp;nbsp;Once the concepts are established, you can always combine and regroup as necessary for the design model, but you don&amp;rsquo;t want to miss anything along the way.&lt;/p&gt;
&lt;p&gt;As a final note, defining conceptual objects is more important than identifying the associations among them, and more time should be spent on object identification, accordingly.&lt;/p&gt;
&lt;h3&gt;Outputs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Domain conceptual model&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That wraps up Day 2 in this series. &amp;nbsp;In Day 3, we&amp;#39;ll&amp;nbsp;Define the Domain Design Model...&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;Enjoy!&lt;br /&gt;Billy McCafferty&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70370" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Lite/default.aspx">S#arp Lite</category></item><item><title>Greenfield Development with ASP.NET MVC &amp; S#arp Lite - Day 1</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2012/08/24/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-1.aspx</link><pubDate>Fri, 24 Aug 2012 17:15:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70292</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;i&gt;A &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2012/08/02/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-introduction.aspx"&gt;series of posts&lt;/a&gt; providing proven guidance for developing ASP.NET MVC applications from idea to well-designed implementation.&lt;/i&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Part I - Planning &amp;amp; Design&lt;/h2&gt;
&lt;p&gt;For the planning and design phase of project delivery, each &amp;quot;day&amp;quot; will have an objective, inputs, activities, and outputs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Objective&lt;/strong&gt;: &amp;nbsp;This is a short description of the goal &amp;ndash; or expected end result &amp;ndash; of the day.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inputs&lt;/strong&gt;: &amp;nbsp;These are the informational inputs, document artifacts, and decisions that should have been made before beginning the day&amp;rsquo;s activities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Activities&lt;/strong&gt;: &amp;nbsp;This is the core element of each day, describing the interactions with the client and the practices used for ultimately transforming ideas into production code. &amp;nbsp;For each day, we&amp;rsquo;ll discuss the activities to be achieved and put them into practice on our example project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Outputs&lt;/strong&gt;: &amp;nbsp;These are the artifacts that will have been generated during the day&amp;rsquo;s activities, some of which may be used as inputs for subsequent days.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Day 1 &amp;ndash; Define the Requirements &amp;amp; Actor/System Interactions&lt;/h2&gt;
&lt;h3&gt;Objective of the Day&lt;/h3&gt;
&lt;p&gt;Work with the client to translate ideas into requirements. &amp;nbsp;By the end of the day, you should be able to concisely describe the project&amp;rsquo;s vision, actors, and implementable requirements.&lt;/p&gt;
&lt;h3&gt;Inputs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Client project ideas, with knowledge of who will be interacting with the system.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Activities&lt;/h3&gt;
&lt;h4&gt;Project Vision&lt;/h4&gt;
&lt;p&gt;The first activity of the day is to establish the project vision. &amp;nbsp;The vision describes the high-level goals of the system and the business case for implementation. &amp;nbsp;It&amp;rsquo;s the two-minute elevator speech describing what the system is intended to achieve.&lt;/p&gt;
&lt;p&gt;While defining the project vision, a key activity will also be to clearly define the &amp;ldquo;actors,&amp;rdquo; or the people who interact with the system and the goal(s) of those interactions, accordingly.&lt;/p&gt;
&lt;p&gt;This may seem like a simple, or even dismissible, step, but clearly defining the vision and actors is one of the most essential elements of the entire project. &amp;nbsp;The vision serves as a good litmus test to use to verify if a client idea is relevant to the project&amp;rsquo;s vision. &amp;nbsp;Additionally, by clearly defining the actors, it allows you and the client to focus on just those requirements which satisfy the needs of those actors; i.e., if an idea comes up which doesn&amp;rsquo;t serve the needs of one of the defined actors, it can be summarily discarded or put on an &amp;ldquo;idea parking lot&amp;rdquo; (so the client feels like you&amp;rsquo;re actually going to look at it again someday&amp;hellip;which you&amp;rsquo;re not). &amp;nbsp;In other words, don&amp;rsquo;t skip this!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Putting it into Practice&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Our aspiring client&amp;rsquo;s company is Acme Telecom. &amp;nbsp;Acme Telecom would like to create a support call tracking system to log and monitor all calls, which will be tracked as &amp;ldquo;support tickets,&amp;rdquo; coming into its support department. &amp;nbsp;Currently, Acme Telecom&amp;rsquo;s paper-based system is making it difficult to assess how well its support staff is responding and closing calls. &amp;nbsp;Acme Telecom doesn&amp;rsquo;t want to try to do too much at once, so the client wants to keep things very simple and small for this first release. &amp;nbsp;Accordingly, the vision that we and the client were able to agree on was as follows:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;i&gt;Acme Telecom&amp;rsquo;s paper-based approach to support call tracking is limiting the company&amp;rsquo;s ability to improve support capabilities. &amp;nbsp;Accordingly, Acme Telecom needs an easy-to-use, secure, web-based Call &amp;amp; Logging System (or &amp;quot;CLogS&amp;quot; for short) for its Support Staff to track and resolve support calls from Customers as &amp;ldquo;support tickets.&amp;rdquo; &amp;nbsp;In addition to facilitating support ticket resolution, the system must provide high-level reporting for Management to filter support ticket logs and to assess key performance metrics, such as rate of resolution and resolution bottlenecks.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Not only does this vision define the general scope of the project, but did you notice that the actors were also clearly stated? &amp;nbsp;(We can even infer hints of the domain model&amp;hellip;but that&amp;rsquo;ll be for a later discussion.)&lt;/p&gt;
&lt;p&gt;Taking the vision a bit further, the actors, and goals of each actor, are as follows:&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Actor&lt;/th&gt;
&lt;th&gt;Major Goals&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support Staff&lt;/td&gt;
&lt;td&gt;Log support ticket.&lt;br /&gt;
Update and/or resolve calls opened by self.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer&lt;/td&gt;
&lt;td&gt;Have support staff resolve calls.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Management&lt;/td&gt;
&lt;td&gt;Run filterable reports on call logs.&lt;br /&gt;
Run &amp;quot;canned reports&amp;quot; to assess resolution performance.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;With that, we have a good general scope definition of the project, we know who the primary stakeholders are, and what each would like to achieve.&lt;/p&gt;
&lt;p&gt;At this stage, it doesn&amp;rsquo;t look like the customer would actually be interacting with the system since they&amp;rsquo;ll be calling the Support Staff directly...should we include them as an actor? &amp;nbsp;Yes, due to the fact that they represent the key stakeholder to be satisfied and should be considered during requirements elaboration by asking &amp;ldquo;Is this idea going to help the Customer get their calls resolved?&amp;rdquo;&lt;/p&gt;
&lt;h4&gt;User Stories or Use Cases?&lt;/h4&gt;
&lt;p&gt;Both User Stories and Use Cases summarize the various features of the system. &amp;nbsp;Each should be small enough to be estimable, but big enough that the client would be willing to pay for its implementation and measure progress. &amp;nbsp;With that said, it is important to decide, very early on, if requirements will be defined using User Stories or Use Cases (or another means altogether) as there are appreciable differences between the two.&lt;/p&gt;
&lt;p&gt;Users Stories, an element of the Scrum/XP, are very short requirement descriptions which are intended to be elaborated during development iterations; they are truly markers for further discussion. &amp;nbsp;A User Story is a feature stated from the perspective of the actor(s) who will benefit from that feature. &amp;nbsp;Each User Story typically includes the following details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Description&lt;/strong&gt;: &amp;nbsp;The feature from the actor&amp;rsquo;s perspective.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Priority&lt;/strong&gt;: &amp;nbsp;Higher priority features should be addressed earlier in the project life-cycle while lower priority features may be dropped in favor of higher priority change requests, or dropped altogether to assist with meeting schedule deadlines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Risk&lt;/strong&gt;: &amp;nbsp;Higher risk User Stories may be A) split into smaller risk User Stories, B) researched to mitigate risk, C) reflected as a higher uncertainty in the estimate, or D) dropped to reduce uncertainty in scope and schedule.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Estimate&lt;/strong&gt;: &amp;nbsp;Typically described in &amp;ldquo;points&amp;rdquo; rather than in hours to better facilitate relative-estimating techniques.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To learn more about User Stories, I encourage you to read &lt;a href="http://www.amazon.com/User-Stories-Applied-Software-Development/dp/0321205685"&gt;User Stories Applied&lt;/a&gt; by Mike Cohn.&lt;/p&gt;
&lt;p&gt;Use Cases, on the other hand, include much more detail for each requirement. &amp;nbsp;For example, while a User Story may be described in a sentence or two, a Use Case describes prerequisites for the Use Case to be activated, a &amp;ldquo;happy path&amp;rdquo; of execution, exceptive cases to execution, and post-conditions, describing the state of the system after completion. &amp;nbsp;To learn more about Use Cases, I encourage you to read &lt;a href="http://www.amazon.com/Applying-Use-Cases-Practical-Guide/dp/0201309815"&gt;Applying Use Cases&lt;/a&gt; by Geri Schneider.&lt;/p&gt;
&lt;p&gt;There are pros and cons to each; &lt;a href="http://bit.ly/T4RhGB"&gt;google&lt;/a&gt; &amp;ldquo;User Story vs. Use Case&amp;rdquo; to get a swath of opinions. &amp;nbsp;Personally, I prefer User Stories if I feel the client is very unsure of what the final system will be, or if the client is supportive of flexible scope; I prefer Use Cases if the end result is very definable or if the client demands fixed bid (which &lt;i&gt;always &lt;/i&gt;makes me shudder). &amp;nbsp;There&amp;rsquo;s more to it than that, but for the purposes at hand, we&amp;rsquo;re going to go with User Stories for Acme Telecom&amp;rsquo;s CLogS application.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Putting it into Practice&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that the vision, actors, and actor-goals have been defined, we&amp;rsquo;re ready to define the requirements of the solution. &amp;nbsp;We&amp;rsquo;ll do so by working with the client to define the requirements as User Stories. &amp;nbsp;To keep things simple, we&amp;rsquo;ll ignore Priority, Risk and Estimate, focusing simply on the description of each. &amp;nbsp;Our User Stories for CLogS are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support Staff may open a new support ticket and provide details including: &amp;nbsp;Customer, Issue Details (such as description and &amp;ldquo;dynamically managed&amp;rdquo; type), Status, and Resolution Details (if resolved immediately). &amp;nbsp;Status of the call may be New, In Progress, or Resolved. &amp;nbsp; (&amp;ldquo;Dynamically managed&amp;rdquo; means that if the issue type isn&amp;rsquo;t available, the Support Staff may enter a new one when entering the support ticket.)&lt;/li&gt;
&lt;li&gt;Support Staff may manage Customer details, adding and updating Customer information when necessary.&lt;/li&gt;
&lt;li&gt;Support Staff may view listing of all tickets opened by self, defaulting to those which are not resolved and filter the listing, accordingly.&lt;/li&gt;
&lt;li&gt;Support Staff may search for an existing support ticket, opened by self, view details of ticket, and update its status and resolution details.&lt;/li&gt;
&lt;li&gt;Management may view listing of all tickets, defaulting to those which are not resolved and filter the listing, accordingly.&lt;/li&gt;
&lt;li&gt;Management may view report showing information regarding how quickly calls are being resolved, called the &amp;ldquo;Ticket Resolution Report by Support Staff.&amp;rdquo; &amp;nbsp;The report may be run for all Support Staff or for a specific Support Staff employee. &amp;nbsp; The manager creating the report may only include Support Staff of whom they are manager.&lt;/li&gt;
&lt;li&gt;Admin may view the &amp;ldquo;Ticket Resolution Report by Support Staff&amp;rdquo; for any and all Support Staff.&lt;/li&gt;
&lt;li&gt;Management may view chart showing a breakdown of call by issue type and average resolution time for each issue type, called the &amp;ldquo;Ticket Resolution Report by Issue Type.&amp;rdquo; &amp;nbsp;The manager creating the report will only see stats for Support Staff of whom they are manager.&lt;/li&gt;
&lt;li&gt;Admin may view the &amp;ldquo;Ticket Resolution Report by Issue Type&amp;rdquo; to include any and all Support Staff.&lt;/li&gt;
&lt;li&gt;Admin may manage all details of Support Staff and Management, along with which Support Staff are assigned to which Manager. &amp;nbsp;Each Support Staff may only have, and must have, one Manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Data Dictionary&lt;/h4&gt;
&lt;p&gt;One of the most frequently skipped steps of project delivery is also one of the simplest and helpful: &amp;nbsp;the creation of a data dictionary. &amp;nbsp;A data dictionary is a simple glossary of domain-related terms which serves to reduce requirements confusion between the client and project delivery team.&lt;/p&gt;
&lt;p&gt;As project requirements become more complicated, a data dictionary becomes increasingly important to ensure everyone is speaking the same language. &amp;nbsp;(Not) surprisingly, it&amp;rsquo;s frequently difficult for even client associates to agree upon term definitions; a data dictionary helps to get people talking and to (hopefully) agree upon the meaning of business terms. &amp;nbsp;Forming this agreement of definitions forms the basis of &lt;a href="http://c2.com/cgi/wiki?UbiquitousLanguage"&gt;Ubiquitous Language&lt;/a&gt;, a prominent component of &lt;a href="http://domaindrivendesign.org/resources/what_is_ddd"&gt;Domain-Driven Design&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A few years back I developed a project management tool for a construction management project. &amp;nbsp;One of the key features of this tool was a Master Budget Report which combined information from various sources to ultimately provide an Estimate at Completion for each project. &amp;nbsp;The report&amp;rsquo;s data columns included Expenditures, Change Orders, Pending Obligations, Remaining Obligations, Total Obligations, and others. &amp;nbsp;It took over three months of workshops involving client stakeholders from the financial group, project controls group, project managers, and upper management to agree upon what constituted a Pending Obligation vs. a Remaining Obligation and to sort out other such definitions and equations associated with the report. &amp;nbsp;Imagine the frustrations that would have ensued if we had tried to develop this &amp;ldquo;standard&amp;rdquo; report when no one agreed to what was actually &amp;ldquo;standard.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The lesson of the story is...don&amp;rsquo;t underestimate the usefulness of a well-discussed data dictionary. &amp;nbsp;And knowing is half the battle.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Putting it into Practice&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Acme Telecom&amp;rsquo;s CLogS is starting to take shape as vaporware; we&amp;rsquo;ve agreed to the vision and even the requirements. &amp;nbsp;But during requirement elaboration discussions, there was some confusion on a few key terms. &amp;nbsp;The following data dictionary helped to alleviate the confusion:&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer&lt;/td&gt;
&lt;td&gt;A person who has an Acme Telecom account number.  (Anyone else is just an annoying person wasting Support Staff&amp;rsquo;s time.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resolution Time&lt;/td&gt;
&lt;td&gt;The number of business days (whole number) to resolve a call is calculated by taking the difference between the day a ticket is opened, and the day when it is resolved, excluding weekends.  If a ticket is resolved in the same day it was opened, its resolution time is 0 days.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avg. Resolution Time&lt;/td&gt;
&lt;td&gt;This is the number of mean business days (decimal number) it takes for an arbitrary group of support tickets to be resolved; i.e., the sum of business days to resolve each ticket divided by the number of tickets.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;It was easy to assume that everyone understood what &amp;quot;resolution time&amp;quot; meant when discussing requirements. &amp;nbsp;But as we attempted to define this term in the data dictionary, it was recognized to be a non-trivial idea. &amp;nbsp;Having this cleared up will help to ensure that anyone using the system has the same understanding of the term...assuming they&amp;rsquo;ve taken five minutes to read the data dictionary, which is quite an assumption in and of itself!&lt;/p&gt;
&lt;p&gt;It should also be noted that the data dictionary was used to not only clarify project-related terms and calculations, but also to clarify the definition of actors.&lt;/p&gt;
&lt;p&gt;While it&amp;rsquo;s not necessary to document every project term, any term which involves tricky calculations, subjectivity in defining, or has been identified as causing disagreement, should certainly be included. &amp;nbsp;Furthermore, the data dictionary may be separated into separate lists such as Actors, Domain, and Calculations, but start simple and expand when necessary.&lt;/p&gt;
&lt;h4&gt;Actor/System Interaction Diagrams&lt;/h4&gt;
&lt;p&gt;I&amp;rsquo;ve been a strong proponent of agile development techniques for years; but a challenge I&amp;rsquo;ve always had is keeping track of the &amp;quot;big picture&amp;quot; as requirements are broken down into more granular requirements as user stories. &amp;nbsp;An associate of mine, Jim Tucker, introduced me to a quick and easy technique that I&amp;rsquo;ve not seen surpassed for expressing the big picture in a clear and concise manner.&lt;/p&gt;
&lt;p&gt;Before delving into technical design, Jim creates &amp;quot;Actor / System Interaction Diagrams&amp;quot; (as UML sequence diagrams) to document how the actors interact with each other and with the underlying system, treating the system as a black box. &amp;nbsp;It&amp;rsquo;s possible to use this technique not only for the overall system, but down to the level of a single user story. &amp;nbsp;This facilitates &amp;quot;zooming in and out&amp;quot; of the details as appropriate.&lt;/p&gt;
&lt;p&gt;This is similar in nature to the back and forth between an actor&amp;rsquo;s actions and system&amp;rsquo;s responses described within a Use Case (an alternative approach to User Stories for documenting feature requirements), and to Craig Larman&amp;rsquo;s &lt;a href="http://www.cse.lehigh.edu/~glennb/oose/ppt/06SystemSequenceDiagrams.ppt"&gt;System Sequence Diagrams&lt;/a&gt; in &lt;a href="http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0130925691"&gt;Applying UML and Design Patterns&lt;/a&gt;. &amp;nbsp;It differs from Use Cases in the fact that it&amp;rsquo;s more graphically oriented, and differs from both in that it may be easily expanded to include many participants and need not be constrained to a single feature. &amp;nbsp;On a recent project, we used this technique to illustrate the high-level interactions among eight actors and multiple third party systems; the end result was simple enough for the client to understand and verify its logic, but expressive enough to be a useful artifact during technical design.&lt;/p&gt;
&lt;p&gt;To use this approach, it&amp;rsquo;s first necessary to understand UML sequence diagrams, which is beyond the scope of this article. &amp;nbsp;(&lt;a href="http://bit.ly/NP0lhD"&gt;Googling&lt;/a&gt; &amp;quot;UML sequence diagrams&amp;quot; will get you going in the right direction.) &amp;nbsp;Having an understanding of sequence diagrams, Actor / System Interaction Diagrams differ from sequence diagrams in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Actors are used in place of classes.&lt;/li&gt;
&lt;li&gt;The system itself is treated as a &lt;i&gt;single&lt;/i&gt; participant in the sequence diagram.&lt;/li&gt;
&lt;li&gt;The &amp;quot;messages&amp;quot; among participants, instead of being API calls, are requests between actors and/or the system itself.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But, as usual, an example speaks a thousand words...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;i&gt;Putting it into Practice&lt;/i&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The trickiest User Story in the CLogS application is as follows:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;i&gt;Support Staff may open a new support ticket and provide details including: &amp;nbsp;Customer, Issue Details (such as description and type), Status, and Resolution Details (if resolved immediately). &amp;nbsp;Status of the call may be New, In Progress, or Resolved.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;This one caused the most discussion and had the most unknowns. &amp;nbsp;Accordingly, it was decided that an Actor / System Interaction Diagram would be created to clarify the sequence of interactions.&lt;/p&gt;
&lt;p&gt;The actors that will be in the sequence diagram include Customer, Support Staff, and the CLogS application. &amp;nbsp;The sequence of events to handle a new support call is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Customer calls Support Staff and describes the issue.&lt;/li&gt;
&lt;li&gt;Support Staff opens a new support ticket in CLogS which requires the following sub-steps:&lt;ol&gt;
&lt;li&gt;Support Staff gets Customer account number.&lt;ol&gt;
&lt;li&gt;Support Staff uses account number to find customer.&lt;/li&gt;
&lt;li&gt;If not found, Support Staff adds a new Customer entry.&lt;/li&gt;
&lt;li&gt;If found (or after created), Support Staff generates a new support ticket for the Customer.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Support Staff adds issue details to the new support ticket entry.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;If resolvable, Support Staff assists the Customer and marks the support ticket as resolved.&lt;/li&gt;
&lt;li&gt;Otherwise, Support Staff gives the Customer the support ticket reference number and pinky swears to resolve the issue and get back with them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/Support-Call-Log-Entry-Creation.png"&gt;&lt;img src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/Support-Call-Log-Entry-Creation.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The&amp;nbsp;Actor / System Interaction Diagram above&amp;nbsp;shows the actors involved and their interactions with each other. &amp;nbsp;Although this level of detail isn&amp;rsquo;t necessary for every User Story, it&amp;rsquo;s a useful technique for illustrating the business processes behind more complex User Stories. &amp;nbsp;Furthermore, this technique need not be limited to the User Story level; alternatively, you could create Actor / System Interaction Diagrams for major modules and/or include third party systems as additional &amp;quot;actors.&amp;quot; &amp;nbsp;UML sequence diagrams are quite versatile for this kind of work.&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;h3&gt;Outputs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Project Vision&lt;/li&gt;
&lt;li&gt;User Stories or Use Cases&lt;/li&gt;
&lt;li&gt;Data Dictionary&lt;/li&gt;
&lt;li&gt;Actor / System Interaction Diagrams&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That wraps up Day 1 in this series. &amp;nbsp;In &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2012/10/12/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-2.aspx"&gt;Day 2&lt;/a&gt;, we&amp;#39;ll&amp;nbsp;Define the Domain Conceptual Model...&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;br /&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70292" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Lite/default.aspx">S#arp Lite</category></item><item><title>Greenfield Development with ASP.NET MVC &amp; S#arp Lite - Introduction</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2012/08/02/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-introduction.aspx</link><pubDate>Thu, 02 Aug 2012 21:08:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:70253</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>8</slash:comments><description>&lt;p&gt;&lt;i&gt;A series of posts providing proven
guidance for developing ASP.NET MVC applications from idea to well-designed
implementation.&lt;/i&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin:4px;" width="350" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/2441931412_5F00_1e5ed90f44_5F00_z.jpg" border="0" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;So you&amp;rsquo;ve landed your first project! &amp;nbsp;Just days ago your client came to you and said &amp;ldquo;I&amp;rsquo;ve got a great idea and I want you to build it!&amp;rdquo; &amp;nbsp;With unwavering confidence, you quickly retorted &amp;ldquo;And I&amp;rsquo;ll build it, and it&amp;rsquo;ll be friggin&amp;rsquo; awesome!&amp;rdquo; &amp;nbsp;You agree to a price, you put all the business paperwork in place, and you&amp;rsquo;re ready to get coding&amp;hellip;you sit down at the computer, raring to go, and think to yourself &amp;ldquo;Now where the hell do I start?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;To begin with, you&amp;rsquo;ve already gotten ahead of yourself. &amp;nbsp;Before a single key stroke of code is developed, it&amp;rsquo;s time to do some planning. &amp;nbsp;And once the planning is done - and only after that - it&amp;rsquo;ll be time to turn those plans into maintainable, tested code.&lt;/p&gt;
&lt;p&gt;While there are plenty of coding samples of design patterns and &amp;quot;best practices,&amp;quot; it&amp;rsquo;s sometimes difficult to figure out how the developer got from an empty directory in Windows Explorer to an implemented piece of architectural and functional beauty. &amp;nbsp;This series of posts will walk you through the basics of the project life cycle, from project inception to project completion, turning ideas into requirements, requirements into plans, and plans into code, with a clear and blatantly unfair bias towards the developer&amp;rsquo;s perspective.&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t intended to discuss a particular project management methodology or advocate the principles of any specific development methodology. &amp;nbsp;Instead, this series&amp;rsquo; focus is on using a number of tricks of the trade of traditional Object Oriented Analysis &amp;amp; Design (OOAD) and various development techniques to turn ideas into working code. &amp;nbsp;In other words, bits and pieces from UML, design patterns, OOAD, Domain-Driven Design , Test-Driven Development , etc&amp;hellip;you know, like what you&amp;rsquo;d do on a real project.&lt;/p&gt;
&lt;p&gt;Although we&amp;rsquo;ll be using &lt;a href="https://github.com/codai/Sharp-Lite/"&gt;S#arp Lite&lt;/a&gt; as the project starting point and architectural infrastructure, most of the principles and techniques we&amp;rsquo;ll be using will be applicable to just about any development implementation you&amp;rsquo;d prefer.&lt;/p&gt;
&lt;p&gt;The project activities will be examined over seven &amp;ldquo;days&amp;rdquo; with each day focusing on a distinct element of project production. &amp;nbsp;Note that each day, when mapped to a real project, may represent an hour, a day, a week, or perhaps even a month(s) depending on the activities involved and the size of the project. &amp;nbsp;(So don&amp;rsquo;t take &amp;quot;day&amp;quot; too literally.)&lt;/p&gt;
&lt;p&gt;The seven days of the project will cover three major themes of project delivery:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/24/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-1.aspx"&gt;Part I&lt;/a&gt; focuses on the planning and design elements of project delivery; i.e., turning project ideas into a workable design. &amp;nbsp;Part I is split into three days:
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/24/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-1.aspx"&gt;Day 1 &amp;ndash; Define the Requirements &amp;amp; Actor / System Interactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/10/12/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-2.aspx"&gt;Day 2 &amp;ndash; Define the Domain Conceptual Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/10/16/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-3.aspx"&gt;Day 3 &amp;ndash; Define the Domain Design Model&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Part II focuses on the implementation phase of project delivery; i.e., turning the design into a working project. &amp;nbsp;Part II is split into four days:
&lt;ul&gt;
&lt;li&gt;Day 4 &amp;ndash; Setup the Project &amp;amp; Security Infrastructure&lt;/li&gt;
&lt;li&gt;Day 5 &amp;ndash; Develop CRUD &amp;amp; Data Management Capabilities&lt;/li&gt;
&lt;li&gt;Day 6 &amp;ndash; Provide Reporting Capabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Part III focuses on extending the project to integrate with third-party, external services with an appropriate separation of concerns.
&lt;ul&gt;
&lt;li&gt;Day 7 &amp;ndash; Integrate with External Services&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While this series of posts walks through the development of the project in a seemingly waterfall fashion, it does not intend to promote such a methodology; indeed, an agile/iterative approach to development is recommended but is beyond the scope of this series to discuss. &amp;nbsp;If you find them useful, I&amp;#39;d encourage you to adapt some or all of the described techniques into your organization&amp;rsquo;s preferred methodology.&lt;/p&gt;
&lt;p&gt;At the end of the series, you should have a basic understanding of how to turn a project idea into a well-designed, maintainable deliverable using real-world techniques, starting from nothing but an idea.&lt;/p&gt;
&lt;h3&gt;Who is the Intended Audience?&lt;/h3&gt;
&lt;p&gt;While I am attempting to write this series to be understandable by any skill level, you&amp;#39;re expected to have basic knowledge of UML (specifically class diagrams and sequence diagrams) and to be familiar with ASP.NET MVC and C#. &amp;nbsp;For materials on these subjects, refer to &lt;a href="http://www.amazon.com/2010-NET-Platform-Andrew-Troelsen/dp/1430225491"&gt;Pro C# 2010 and the .NET Platform&lt;/a&gt; [Troelsen 2010], &lt;a href="http://www.amazon.com/Professional-ASP-NET-MVC-Wrox-Programmer/dp/1118076583"&gt;Professional ASP.NET MVC 3&lt;/a&gt; [Galloway 2011], and &lt;a href="http://www.amazon.com/UML-2-0-Pocket-Reference-OReilly/dp/0596102089"&gt;UML 2.0 Pocket Reference&lt;/a&gt; [Pilone 2006]. &amp;nbsp;Other references will be provided along the way to help fill in any missing gaps and secondary subjects.&lt;/p&gt;
&lt;p&gt;Developers of experienced-beginner to intermediate levels will gain the most from this series.&lt;/p&gt;
&lt;p&gt;The next post in this series is &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2012/08/24/greenfield-development-with-asp-net-mvc-amp-s-arp-lite-day-1.aspx"&gt;Day 1 &amp;ndash; Define the Requirements &amp;amp; Actor/System Interactions&lt;/a&gt;...&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;br /&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=70253" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Lite/default.aspx">S#arp Lite</category></item><item><title>Checklist for Developing Message-Based Systems</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/23/checklist-for-developing-message-based-systems.aspx</link><pubDate>Tue, 23 Mar 2010 21:22:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:56236</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;Even when developing the most basic CRUD application, we ask ourselves a number of questions - whether we realize it or not - during the initial phases of development concerning the architecture and construction of the project.&amp;nbsp; Where will the data be persisted?&amp;nbsp; What mechanism will be used to communicate with the database?&amp;nbsp; How will data from the database be transformed into business objects?&amp;nbsp; Should separated interfaces and dependency injection be employed to maintain a clean separation of concerns between application logic and data access objects?&amp;nbsp; What UI components will be leveraged to speed development of the UI layer?&amp;nbsp; When developing message-based systems (see &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/01/message-based-systems-for-maintainable-asynchronous-development.aspx"&gt;Message-Based Systems for Maintainable, Asynchronous Development&lt;/a&gt; for an introduction) it&amp;#39;s immensely helpful to formalize such questions about how the systems will be designed and developed.&amp;nbsp; Creating a checklist of such items to decide upon, and formalizing answers for the application context, helps to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Standardize how components (applications participating in the message-based system) will communicate with the messaging middleware;&lt;/li&gt;
&lt;li&gt;Provide architectural guidance throughout project development concerning how components will leverage message end-points;&lt;/li&gt;
&lt;li&gt;Define the data model that will be used for sending commands and exchanging data among components;&lt;/li&gt;
&lt;li&gt;Assist new developers on the team with getting up to speed with maintaining and extending the message-based system; and&lt;/li&gt;
&lt;li&gt;Support consistency (and predictable maintainability) amongst the components of the system.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This post provides an addendum, if you will (I&amp;#39;m sure you will), to &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/01/message-based-systems-for-maintainable-asynchronous-development.aspx"&gt;Message-Based Systems for Maintainable, Asynchronous Development&lt;/a&gt;&amp;nbsp;for complementing the article with a checklist of questions and architectural topics that should be discussed, decided upon, and/or spiked before beginning development of your budding message-based system. &amp;nbsp;Accordingly, this does not describe a methodology for developing message-based systems, but simply a checklist of topics which should be taken into consideration before development begins.&amp;nbsp; Many of the checklist items below serve as good starting points for team discussion and for the development of architectural spikes for demonstrating implementation details.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Messaging Middleware&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What messaging middleware solution will form the background of the message-based system?&lt;/li&gt;
&lt;li&gt;How are channels addressed in the selected middleware? &amp;nbsp;(E.g., as a string or as a port number?)&lt;/li&gt;
&lt;li&gt;How does the nomenclature of the middleware match up to standard elements of message-based systems and design patterns? &amp;nbsp;E.g., in &lt;a href="http://www.ros.org/wiki/"&gt;Robot Operating System (ROS&lt;/a&gt;), a channel is called a &amp;quot;topic.&amp;quot; &amp;nbsp;Likewise, is their middleware specific nomenclature for elements such as component, publisher, subscriber, point-to-point channel, publish/subscribe channel, message, command message, request-reply message, router, message end-point, and other messaging design patterns?&lt;/li&gt;
&lt;li&gt;What mechanism is available for peeking at messages going over a point-to-point channel?&lt;/li&gt;
&lt;li&gt;What utilities are available for viewing active channels, publishers, and subscribers?&lt;/li&gt;
&lt;li&gt;What other tools does the middleware provide for debugging and observing the messaging system? &amp;nbsp;Will custom utilities need to be developed to autment development and debugging capabilities?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Integration with Messaging Middleware&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How will message end-points publish a messages?&lt;/li&gt;
&lt;li&gt;How will message end-points subscribe to a channel for messages?&lt;/li&gt;
&lt;li&gt;How will message end-points poll a channel?&lt;/li&gt;
&lt;li&gt;What technique will be used to decouple the component (participating application) from the message end-point when sending a message? &amp;nbsp;E.g., dependency injection, separated interface, or other?&lt;/li&gt;
&lt;li&gt;What technique will be used to decouple the component from the message end-point when receiving a message or polling a channel? &amp;nbsp;E.g., callback, separated interface, or other?&lt;/li&gt;
&lt;li&gt;Should exceptions raised by the messaging middleware be wrapped in component specific exceptions for looser coupling? &amp;nbsp;If so, what will be the standard exceptions? &amp;nbsp;Additionally, how will such exceptions be logged and tracked for debugging; e.g., email alerts, logging, exception message channel?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Channels and Routing&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;What channels will be created and what data type should each channel carry?&lt;/li&gt;
&lt;li&gt;Will a hierarchical naming strategy be leveraged for naming and organizing channels? &amp;nbsp;If so, what are the naming conventions for the project?&lt;/li&gt;
&lt;li&gt;Has an invalid message channel been setup with a logger to capture and record invalid messages?&lt;/li&gt;
&lt;li&gt;How should a predictive router be implemented, when needed?&lt;/li&gt;
&lt;li&gt;How should a reactive router (e.g., a message filter) be implemented, when needed?&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Message Elements&lt;/strong&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;What data elements may the header of a message contain and how should each be specified? &amp;nbsp;E.g., return address, message expiration, timestamp, origin, format indicator, etc.&lt;/li&gt;
&lt;li&gt;How should a message identifier and correlation identifier be generated and included in the header?&lt;/li&gt;
&lt;li&gt;What is the messaging data model supported and/or enforced by the messaging middleware? &amp;nbsp;E.g., ROS supports&amp;nbsp;&lt;a href="http://www.ros.org/wiki/msg"&gt;http://www.ros.org/wiki/msg&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;What canonical data model will be used to imbue message content with domain specific semantic meaning? &amp;nbsp;E.g., &lt;a href="http://en.wikipedia.org/wiki/JAUS"&gt;JAUS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;How will message translators and/or message mappers be leveraged for converting between each component&amp;#39;s domain model and the canonical data model?&lt;/li&gt;
&lt;li&gt;How will a command, document, event and request-reply message be composed?&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Other Topics&lt;/strong&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;How will components maintain information that is associated with a correlation identifier?&lt;/li&gt;
&lt;li&gt;Are there existing components which need to interact with the messaging middleware which cannot be modified?&amp;nbsp; If so, how will each communicate with the messaging middleware?&lt;/li&gt;
&lt;li&gt;How will each component participate with the message based system; e.g., as a polling consumer, as an event-driven consumer, as strictly an event publisher, as a combination of these?&lt;/li&gt;
&lt;li&gt;Should exceptions raised by a component participate in a global exception tracking and debugging mechanism?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As stated previously, this checklist is not intended to provide a methodology for developing message-based systems, but should serve as a good basis to make sure &amp;quot;T&amp;#39;s are crossed and I&amp;#39;s are dotted&amp;quot; when deciding upon the major architectural aspects and development techniques that will be leveraged throughout the development of your (team&amp;#39;s) message-based system.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;br /&gt;Billy McCafferty&lt;/p&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=56236" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Quality+Assurance/default.aspx">Quality Assurance</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Robotics/default.aspx">Robotics</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>A Few Thoughts on DDD, DTOs, View Models, Repositories and Separation of Concerns</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/06/a-few-thoughts-on-ddd-dtos-view-models-cqs-repositories-and-separation-of-concerns.aspx</link><pubDate>Sat, 06 Mar 2010 16:41:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55672</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>15</slash:comments><description>&lt;p&gt;What I&amp;#39;ve loved most about developing an open-source project is the ideas that I get from others who look at the work and either A) validate ideas, B) suggest that something stinks, or C) call a royal WTF and force people (e.g., me) &amp;nbsp;to explain ideas more fully. &amp;nbsp;It&amp;#39;s usually during these explanation attempts that light bulbs start to come on and ideas are refactored and become more substantiated (or at least more defendable). &amp;nbsp;The S#arp Architecture forums have been a gold mine, IMO, for the discussion of the practical application of balanced DDD techniques on real-world projects. &amp;nbsp;After feedback that I&amp;#39;ve already gotten on my recent &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx"&gt;post concerning application services and CQS&lt;/a&gt;&amp;nbsp;and listening to and adding my two cents concerning ideas on the S#arp forums, I&amp;#39;d like to share a few ideas (that I shared on the forum) concerning drawing the line among application layers, the management of DTOs and View Models, and a general discussion of separation of concerns. &amp;nbsp;(As &lt;a href="http://panteravb.com/blog/posts/2009/1/9/because-thats-how-they-do-it-in-sharp-architecture.ashx"&gt;Chris Carter correctly (and a tad bluntly) explained&lt;/a&gt;, don&amp;#39;t take these ideas at face value...use them as a point of discussion and contemplation to come to your own conclusions with your project team...and let me know what you think.)&lt;/p&gt;
&lt;p&gt;Every great developer knows that any problem can be solved by adding another layer of abstraction. &amp;nbsp;;)&lt;/p&gt;
&lt;p&gt;Obviously, with additional layers of abstraction and indirection, we also introduce complexity and additional objects which need to be maintained. &amp;nbsp;Over the past year, I have had struggles concerning just how far the &amp;quot;DTO paradigm&amp;quot; should be taken to effectively separate layers from the domain and &amp;quot;best practices&amp;quot; for how they should be used. &amp;nbsp;I don&amp;#39;t think the answer can be found in a best practice (but I also hate to leave it simply at &amp;quot;it depends&amp;quot;). &amp;nbsp;I truly feel that the most important practice is for a project development team to decide, and firmly agree upon, which approach will be taken on a project and for the agreed upon approach to be followed with discipline (and enforced via code reviews) by the team.&lt;/p&gt;
&lt;p&gt;On a couple of recent projects, the biggest problems we ran into weren&amp;#39;t concerning &lt;i&gt;which&lt;/i&gt;&amp;nbsp;approach to leveraging DTO for layer separation was &amp;quot;best,&amp;quot; but on coming to a firm layering decision and having the team discipline to adhere to those practices. &amp;nbsp;Because of these &amp;quot;gray&amp;quot; areas, which we didn&amp;#39;t come to a firm team agreement on, there were inconsistent practices used by the developers which led to rot, particularly between the controller (or code-behind) and application services layer.&lt;/p&gt;
&lt;p&gt;So while we can discuss which approach is best or most effective, I think the greater concern is for the team to pick a direction, to stick to it, and to diverge or refactor as a team decision.&lt;/p&gt;
&lt;p&gt;But as I said, I don&amp;#39;t want to leave it at &amp;quot;it depends.&amp;quot; ;) &amp;nbsp;So after reading everyone&amp;#39;s ideas here and contemplating further on past projects and the ideas I recently put forth in &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx"&gt;http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx&lt;/a&gt;, here are a couple of ideas that I&amp;#39;ve been trying to adhere to (and/or will be adhering to on my next project). &amp;nbsp;The layers referenced below may be viewed in a &lt;a href="http://github.com/codai/Sharp-Architecture/raw/master/docs/ProjectArchitecture.PNG"&gt;package diagram here&lt;/a&gt;&amp;nbsp;for better clarity of what&amp;#39;s discussed.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usually, one object should be used to populate a form while a second should be used to collect data from a form. &amp;nbsp;The former would contain information for&amp;nbsp;default/selected values along with&amp;nbsp;drop-down values, for examples, while the latter would encapsulate which options were selected when the user submitted the form. &amp;nbsp;Personally, I use a &amp;lt;EnityName&amp;gt;FormViewModel to populate the form and use an entity to collect from the form...but I see it equally valid to instead use an intermediary DTO to collect from the form if further separation is warranted. &amp;nbsp;Additionally, I feel it is OK for a FormViewModel object to have references to domain objects to make it easier to transfer data to the form for input population. &amp;nbsp;This is an arguable point and would be just as valid to only pass DTOs in the view model for a cleaner separation between view and domain, with the acceptance that there will be more objects and maintenance that comes with that approach.&lt;/li&gt;
&lt;li&gt;I believe that view models should be maintained either in the application services layer OR in a separate ViewModels class library if a project team feels the additional separation is warranted (although I can&amp;#39;t envision much reason to do so). &amp;nbsp;(I&amp;#39;ll be modifying my sample project post to reflect the former.) &amp;nbsp;Either way, they should not be maintained in .Core to keep a very clean separation from domain concerns. &amp;nbsp;While the name &amp;quot;ViewModel&amp;quot; implies that they are a view concern, they only describe &lt;i&gt;what&lt;/i&gt;&amp;nbsp;should be displayed, not &lt;i&gt;how&lt;/i&gt; it should be displayed. &amp;nbsp;Accordingly, there is still a very clear separation of concerns between the view layer (which the user interacts with) and the view model classes. &amp;nbsp;Furthermore, the application services expose methods which should be usable by any type of client. &amp;nbsp;In line with this, a ViewModel or FormViewModel class does not impart a particular mechanism for the implementation of the view layer - again, it only describes &lt;i&gt;what&lt;/i&gt;&amp;nbsp;data should be available to the view. &amp;nbsp;So even if view model classes are maintained in app services, this does not preclude there use by various client types; e.g., they could be equally consumed by ASP.NET, ASP.NET MVC, Spark, SilverLight, etc. &amp;nbsp;(The only caveat is that if the view model classes maintain references to domain objects, then it will be more difficult to expose them for serialization via web services and WCF. Accordingly, a project team should firmly decide if ViewModels may contain references to domain objects.)&lt;/li&gt;
&lt;li&gt;I believe that DTOs should be maintained in a separate assembly and have no reference to .Core or be maintained in .Core if warranted with the acceptance of decreased &amp;quot;shareability.&amp;quot; &amp;nbsp;DTOs should almost always be serializable; i.e., transferable via web services and WCF. &amp;nbsp;This allows the DTOs class library to be easily shared with a consumer of web services which may expose these objects, for easier deserialization. &amp;nbsp;Some of the motivations for deciding when to use DTOs would be to provide a clean separation between the view and app services (if a project team feels its warranted), to expose data to web service consumers, and to better enable Command/Query Separation.&lt;/li&gt;
&lt;li&gt;Repositories may return Entities, Value Objects or DTOs, in addition to other &amp;quot;basic&amp;quot; types; e.g., primitives, arrays, etc. &amp;nbsp;Ideally, repositories would not be used by domain objects (even via their interfaces) and would have their interfaces maintained in the application services layer. &amp;nbsp;If the repository interfaces are maintained in .Core, then this forces DTOs to be maintained in .Core as well with the possibility that domain references may &amp;quot;leak&amp;quot; into DTOs. &amp;nbsp;If the repository interfaces are maintained in .ApplicationServices, then DTOs may be maintained in a cleanly separated library without worrying about the line between DTOs and domain objects being grayed. &amp;nbsp;But data interfaces (and DTOs) may be maintained in .Core if the team feels the simplification is warranted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With all this said, I still think the most important decision is deciding a path to take for your project, having the project team agree upon it, and maintaining the discipline to stay on course.&lt;/p&gt;
&lt;p&gt;Your feedback on these ideas is most welcome!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55672" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DeepThoughtsByJackHandey/default.aspx">DeepThoughtsByJackHandey</category></item><item><title>Better Application Services and CQS using S#arp Architecture 1.0 Q3 2009</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/05/better-application-services-and-cqs-with-s-arp-architecture-1-0-q3-2009.aspx</link><pubDate>Fri, 05 Mar 2010 18:47:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55653</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>8</slash:comments><description>&lt;p&gt;&lt;i&gt;Updated 2010.03.09 to reflect small modifications that were decided through subsequent discussions on S#arp forum and other DDD posts.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Obviously, &lt;a href="http://wiki.sharparchitecture.net/"&gt;S#arp Architecture&lt;/a&gt; is the bee&amp;#39;s knees when it comes to developing ASP.NET MVC applications. ;) &amp;nbsp;But as a project evolves and gets larger, &amp;quot;out of the box&amp;quot; S#arp Architecture 1.0 guidance runs into a few pain points. &amp;nbsp;Particularly, there&amp;#39;s poor use of the &lt;a href="http://martinfowler.com/eaaCatalog/serviceLayer.html"&gt;application services&lt;/a&gt; layer, the separation between controllers and application services is not very clear, entity listing pages become performance bottlenecks as the domain model gets sizable, there is no &lt;a href="http://devlicio.us/blogs/casey/archive/2009/02/12/ddd-command-query-separation-as-an-architectural-concept.aspx"&gt;command/query separation (CQS)&lt;/a&gt;&amp;nbsp;&amp;quot;out of the box&amp;quot;, and unit tests require re-occurring&amp;nbsp;maintenance to deal with changes in the number of constructor parameters to controllers and application services. &amp;nbsp;While the amicable and adroit&amp;nbsp;&lt;a href="http://weblogs.asp.net/alecwhittington/default.aspx"&gt;Alec Whittington&lt;/a&gt;&amp;nbsp;(who is taking over the lead role from me on S#arp Architecture) is hard at work upgrading S#arp Architecture to accommodate recent dependency upgrades and accommodating ASP.NET MVC 2, I wanted to take a stab at resolving some of the architectural issues that I&amp;#39;ve run into, on S#arp projects over the past year.&lt;/p&gt;
&lt;p&gt;
        I&amp;#39;ve developed and included a sample project, built on S#arp Architecture 1.0 Q3 2009, for the following key reasons:
        &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To resolve some &amp;quot;pain points&amp;quot; that develop as S#arp projects grow to large sizes,&lt;/li&gt;
&lt;li&gt;To demonstrate better use of the application services layer,&lt;/li&gt;
&lt;li&gt;To demonstrate better command/query separation of the entity listing pages for dramatically 
            better performance as the domain model grows,&lt;/li&gt;
&lt;li&gt;To create an architectural spike for a new project I&amp;#39;m working on, and&lt;/li&gt;
&lt;li&gt;To collect feedback from the S#arp community to determine if this is an 
            appropriate architectural direction for the next release of S#arp Architecture.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
        Please post any feedback and/or suggestions you may have in the comments below or, more preferably, to the S#arp Architecture forums at 
        &lt;a href="http://groups.google.com/group/sharp-architecture"&gt;http://groups.google.com/group/sharp-architecture&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Setup instructions&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Unzip the sample project to a BetterAppServices folder&lt;/li&gt;
&lt;li&gt;Create a new database called BetterAppServices&lt;/li&gt;
&lt;li&gt;Using SQL Enterprise Manager, run:
	&lt;ol&gt;
&lt;li&gt;/BetterAppServices/db/Schema/CreateBetterAppServicesDb_ChangesWillBeLost.sql&lt;/li&gt;
&lt;li&gt;/BetterAppServices/db/StoredProcedures/CreateGetProductCategorySummaries.sql&lt;/li&gt;
&lt;li&gt;/BetterAppServices/db/StoredProcedures/CreateGetProductSummaries.sql&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Open /BetterAppServices/BetterAppServices.sln with VS 2008&lt;/li&gt;
&lt;li&gt;In VS 2008, open BetterAppServices.Web/NHibernate.config and change the connection string to point to your BetterAppServices database&lt;/li&gt;
&lt;li&gt;Right click the BetterAppServices.Web project and &amp;quot;Set as StartUp Project&amp;quot;&lt;/li&gt;
&lt;li&gt;Run (F5) the project to see everything in action.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Changes from &amp;quot;out of the box&amp;quot; S#arp Architecture 1.0 Projects&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;
        This project is more of an architectural spike more than anything else at the moment.  
        Accordingly, the CRUD scaffolding generator has been removed and non-essential unit tests 
        have been removed to focus on the architecture itself. &amp;nbsp;Many of the changes will be 
        incorporated into the S#arp CRUD scaffolding generator; this will either be available in the next
        release, or will be provided as an add-on, as this new approach &lt;i&gt;does&lt;/i&gt; add complexity and 
        introduces a major breaking change to existing 1.0 projects.
    &lt;/p&gt;
&lt;p&gt;
        Major changes include:
        &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
                /db Folder Changes
                
&lt;ul&gt;
&lt;li&gt;Added /db/Schema/CreateBetterAppServicesDb_ChangesWillBeLost.sql.  
                    This gets auto-regenerated when unit tests are run.  The motivation was to have the DB 
                    schema automatically maintained while developing.&lt;/li&gt;
&lt;li&gt;Added /db/StoredProcedures/CreateGet&lt;i&gt;EntityNamePlural&lt;/i&gt;Summaries.sql.  These SPs provide 
                    command/query separation for the entity listing (Index.aspx) pages, which frequently became a 
                    performance bottleneck.
                    &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                Cross-Project Changes
                
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;Moved /BetterAppServices.Core/DataInterfaces/* to /BetterAppServices.ApplicationServices/DataInterfaces/.  
                    &lt;strong&gt;This is the only major, possible breaking change for existing applications.&lt;/strong&gt;  This was done to further 
                    remove the potential of domain objects using data repositories directly, and to allow the repositories 
                    to return objects from a new Dtos project for command/query separation, among other benefits (dicussed below).&lt;/span&gt;&amp;nbsp;&amp;nbsp;Decided not to do this to support domain services which may require the use of repositories and to make upgrading from previous version much simpler in some cases. &amp;nbsp;Having the interfaces in .Core doesn&amp;#39;t necessitate that domain objects use them; in fact, my rule of thumb is for all domain objects to avoid the use of repositories unless an exceptive case exists.&lt;/li&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;Replaced all uses of &amp;quot;using BetterAppServices.Core.DataInterfaces;&amp;quot; to 
                    &amp;quot;using BetterAppServices.ApplicationServices.DataInterfaces;&amp;quot; to support the above mentioned change.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Replaced all uses of IRepository&lt;i&gt;EntityName&lt;/i&gt; with I&lt;i&gt;EntityName&lt;/i&gt;Repository.  Be default, all 
                    entities now have an explicit repository.  This avoids the need to manually change from the generic to 
                    the explicit, when the need arose, in unit tests and in constructors; which was frequently occurring.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Core/QueryDtos (/BetterAppServices.Dtos)
&lt;ul&gt;
&lt;li&gt;&lt;span style="text-decoration:line-through;"&gt;Added a Dtos class library to provide an appropriate location for View Models and DTOs.  While this project 
                    currently has a dependency on BetterAppServices.Core, so that the View Models can contain references to 
                    domain objects, this dependency could be severed for better separation between the view and the domain. 
                    The caveat is that much more work would be required maintaining a more complete DTO layer and transferring 
                    data via DTOs in all of the CRUD pages.&lt;/span&gt;&amp;nbsp;&amp;nbsp;Decided that a separate assembly was overkill. &amp;nbsp;Consequently, added this namespace to contain query DTOs for transferring results of &amp;quot;report&amp;quot; queries into objects. &amp;nbsp;With this example project, only the listing page uses &amp;quot;pure&amp;quot; DTOs 
                    for much better performance.  The other CRUD pages still communicate directly with domain objects to keep 
                    things much simpler. This is something that can be argued either way and it should depend on the 
                    project needs to determine if a more separated approach is warranted.&lt;/li&gt;
&lt;li&gt;Added&amp;nbsp;&lt;i&gt;EntityName&lt;/i&gt;Dto.cs to act as a summary object to be bound to results from stored procedures (e.g., the entity listing pages), or other DTO needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;/BetterAppServices.ApplicationServices/ViewModels
&lt;ul&gt;
&lt;li&gt;Added this namespace and&amp;nbsp;&lt;i&gt;EntityName&lt;/i&gt;FormViewModel.cs to hold data related to adding and updating the &lt;i&gt;EntityName&lt;/i&gt;.  
                    This object gets populated and passed to the entity form pages, accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.ApplicationServices
                
&lt;ul&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos so that app services can return DTOs.&lt;/li&gt;
&lt;li&gt;Added &lt;i&gt;EntityName&lt;/i&gt;ManagementService.cs.  This app service class removes the CRUD logic 
                    from the controllers, makes the logic more reusable, and creates an appropriate class to add 
                    additional application service logic to.&lt;/li&gt;
&lt;li&gt;Added I&lt;i&gt;EntityName&lt;/i&gt;ManagementService.cs.  This app service interface makes unit testing more 
                    maintainable because you can mock the service interface and not worry about when the concrete class&amp;#39; 
                    constructor arguments change.&lt;/li&gt;
&lt;li&gt;Added /DataInterfaces/I&lt;i&gt;EntityName&lt;/i&gt;Repository.cs.  As described above, every entity now has 
                    an explicit repository interface to avoid changes down the road when custom interfaces would inevitably 
                    be introduced.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Data
                
&lt;ul&gt;
&lt;li&gt;Added /BetterAppServices.Data/&lt;i&gt;EntityName&lt;/i&gt;Repository.cs to implement the associated interface. 
                    An important thing to note is that method provided invokes a stored procedure to act as a reporting means in 
                    line with command/query separation.  This is useful for entity listing pages which would frequently, previously, 
                    end up loading a huge portion of the domain model to show summary information.&lt;/li&gt;
&lt;li&gt;Added /BetterAppServices.Data/NamedQuery/Get&lt;i&gt;EntityName&lt;/i&gt;Summaries.hbm.xml and set its compile action to 
                    &amp;quot;Embedded Resource.&amp;quot;  This provides the &amp;quot;short cut&amp;quot; for invoking the stored procedure.  It could easily be modified 
                    to accept paging parameters.&lt;/li&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos so that repositories can return DTOs for better command/query 
                    separation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Web
                
&lt;ul&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos to be able show DTOs on web pages.&lt;/li&gt;
&lt;li&gt;Changed ComponentRegistrar.AddCustomRepositoriesTo &amp;quot;BetterAppServices.Core&amp;quot; to 
                    &amp;quot;BetterAppServices.ApplicationServices&amp;quot; to reflect the new location of the data repository interfaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Web.Controllers
                
&lt;ul&gt;
&lt;li&gt;Added reference to BetterAppServices.Dtos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
                /BetterAppServices.Tests
                
&lt;ul&gt;
&lt;li&gt;Modified MappingIntegrationTests.CanGenerateDatabaseSchema to save DB schema to 
                    /db/Schema/CreateBetterAppServicesDb_ChangesWillBeLost.sql every time the unit test is run.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
        
        To reiterate, many of the changes above can be incorporated into a CRUD scaffolding generator; the focus with this example 
        project is on providing an archtectural spike of the proposed architectural revisions.&lt;/p&gt;
&lt;p&gt;Even if you don&amp;#39;t use S#arp Archtiecture, this sample project should serve as a good example of using application services and basic use of command/query separation (CQS). &amp;nbsp;Although the CQS in the sample project could be taken much further, I felt that the sample provides a good balance between practical maintainability and a more austere separation of concerns.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55653" width="1" height="1"&gt;</description><enclosure url="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.05.56.53/BetterAppServices.rar" length="2841490" type="application/octet-stream" /><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Architecture/default.aspx">S#arp Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category></item><item><title>Message-Based Systems for Maintainable, Asynchronous Development</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2010/03/01/message-based-systems-for-maintainable-asynchronous-development.aspx</link><pubDate>Tue, 02 Mar 2010 04:22:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55589</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>8</slash:comments><description>&lt;p&gt;&lt;strong&gt;Preface&lt;/strong&gt; (you know it&amp;rsquo;s good if there&amp;#39;s a preface)&lt;/p&gt;
&lt;p&gt;In &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2010/02/03/software-architectural-approaches-for-robotics.aspx"&gt;Architectural Paradigms of Robotic Control&lt;/a&gt;, a number of architectures were reviewed including deliberative, reactive, and hybrid architectures. &amp;nbsp;Each of these exhibit a clean separation of concerns with layering and encapsulation of defined behaviors. &amp;nbsp;When implemented, the various capabilities, such as planners and mobility controllers, are encapsulated into discrete components for better reusability and maintainability. &amp;nbsp;A pivotal aspect &lt;i&gt;not&lt;/i&gt; discussed in the previous article is how the various system layers and components communicate with each other, such as reporting sensor feedback and sending commands to actuator controllers. &amp;nbsp;Effectively resolving this communication challenge is not only important to robotic systems but to many other industries and domains for the successful integration of disparate applications.&lt;/p&gt;
&lt;p&gt;To give credit where credit is due, this article pulls quite heavily&amp;nbsp;from the patterns, taxonomy, and best practices presented in&amp;nbsp;&lt;a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683"&gt;Enterprise Integration Patterns&lt;/a&gt;&amp;nbsp;(Hohpe, 2003). &amp;nbsp;This well organized book is chock full of hard learned lessons and solid guidelines for developing maintainable message-based systems. &amp;nbsp;This article should not be seen as an adequate replacement for that book (it&amp;rsquo;s more like cliff notes with a spackling of robotics bias); indeed,&amp;nbsp;&lt;a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683"&gt;Enterprise Integration Patterns&lt;/a&gt;&amp;nbsp;should have a prominent place on your bookshelf if you&amp;#39;re developing message-based systems&amp;nbsp;&amp;ndash;&amp;nbsp;so read this post and then browse&amp;nbsp;&lt;a href="http://www.eaipatterns.com/"&gt;http://www.eaipatterns.com/&lt;/a&gt;&amp;nbsp;while waiting for your copy to arrive to delve deeper.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A Need for Message-Based Systems&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A few industries in particular, such as finance, healthcare and robotics, are demanding integration of an intimidating number of separate technologies that may be spread across computers, networks, and/or built upon a variety of technological platforms. &amp;nbsp;Not only is this integration tricky, it can come with a significant cost to performance and maintainability if not implemented correctly. &amp;nbsp;Accordingly, a solution is needed which facilitates loosely coupled integration while accommodating the performance demands of the task at hand. &amp;nbsp;Taking a message-oriented approach to inter-application communications is one such way to accommodate these demands in a maintainable manner without sacrificing performance. &amp;nbsp;This article gives an introduction to developing message-based systems using messaging middleware, describes taxonomy for discussing messaging topics and patterns, and includes a number of best practices.&lt;/p&gt;
&lt;p&gt;Before delving further, it&amp;#39;s important to clarify a few terms that will be used frequently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Messaging Middleware&lt;/i&gt; (aka, a message bus): &amp;nbsp;a 3rd party application which provides messaging infrastructure and capabilities (e.g., &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/msmq/default.mspx"&gt;MSMQ&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/bb648752.aspx"&gt;MS Concurrency and Coordination Runtime&lt;/a&gt; (CCR), &lt;a href="http://www.ros.org/wiki/"&gt;Robot Operating System&lt;/a&gt; (ROS)),&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Component&lt;/i&gt;: &amp;nbsp;a stand-alone application or piece of executable code which communicates with the messaging middleware,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Message-based system&lt;/i&gt;: &amp;nbsp;the entirety of the system including all integrated components and the messaging middleware.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As stated, messaging provides one means of facilitating inter-component communications. &amp;nbsp;But as with any design approach, the project requirements must be carefully considered to determine if messaging is the appropriate mechanism for integration. &amp;nbsp;While messaging is robust and facilitates integration, it also adds complexity and indirection. &amp;nbsp;So before deciding to use messaging as the means of integration, consider all component integration options including (Hohpe, 2003):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;File Transfer&lt;/i&gt;: &amp;nbsp;wherein a component produces files of shared data which other components consume,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Shared Database&lt;/i&gt;: &amp;nbsp;each component stores and retrieves data from a common database,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Remote Procedure Invocation&lt;/i&gt;: &amp;nbsp;each component exposes specific procedures to be invoked remotely for exposing behavior and exchanging data,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Messaging&lt;/i&gt;: &amp;nbsp;each component connects to a common messaging system, using messages to invoke behavior and exchange data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Determining which integration approach is most suitable to your project&amp;#39;s needs is beyond the scope of this article, focusing instead specifically on messaging. &amp;nbsp;In turn, we&amp;#39;ll review important elements of developing a message-based system including: &amp;nbsp;message channels, messages, message routers, and message endpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Channels&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When a component sends information to another component in a message-based system, it adds the information to a &lt;i&gt;message channel&lt;/i&gt;. &amp;nbsp;The receiving component then retrieves the information from the message channel. &amp;nbsp;Different channels are created for each kind of data to be carried; having a separate channel for each datatype better enables receiving components to know what kind of data will be retrieved from a given channel. &amp;nbsp;For using a channel, each channel is addressable for sending and retrieving messages to/from them. &amp;nbsp;How a channel is addressed varies depending on the messaging middleware being leveraged, but it&amp;#39;s usually a port number or a unique string identifier. &amp;nbsp;As a good practice for keeping channels organized, if string identifiers are available, a hierarchical naming convention may be employed to label channels by type and name; e.g., a channel carrying laser scans might be called &amp;quot;Perception/LaserScans.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/ChannelTypes.png" style="border:0;float:right;margin-top:6px;margin-bottom:6px;margin-left:2px;margin-right:2px;" alt="" /&gt;There are two basic kinds of message channels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Point-to-Point Channels&lt;/i&gt; (aka - client/server style): &amp;nbsp;routes messages for components to talk directly with other components; e.g., a remote procedure call to another component. &amp;nbsp;A message over a point-to-point channel only has a single receiver; so while the sender may not necessarily know who the receiver is, the sender can rest assured that the message will only be received by one receiver &amp;ndash; it&amp;rsquo;s a &lt;a href="http://en.wikipedia.org/wiki/FIFO"&gt;FIFO&lt;/a&gt; queue.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Publish-Subscribe Channels&lt;/i&gt; (aka - broadcast): &amp;nbsp;routes messages for components to publish data and an arbitrary number of components to subscribe to that data. &amp;nbsp;A copy of the message is generated for each subscriber on the channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition to channels intended to carry information among components, it is a good practice to setup an &lt;i&gt;invalid message channel&lt;/i&gt;&amp;nbsp;that bad-formed or unreadable messages may be forwarded to for logging and to assist with debugging.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Messages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With a function call, a simple parameter or object reference may be passed and retrieved by the invoked method, sharing the same memory space. &amp;nbsp;But when passing data between two processes with separate memory spaces, the data must be packaged into a &amp;quot;message&amp;quot; adhering to an agreed upon format which the receiver will be able to disassemble and understand. &amp;nbsp;The sender of the message passes the message via a message channel. &amp;nbsp;The receiver retrieves the message from the message channel and transforms the message into internal data structures appropriate for the task at hand.&lt;/p&gt;
&lt;p&gt;A message is made up of two parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Header&lt;/i&gt;: &amp;nbsp;describes the data being transmitted and details concerning the message itself; e.g., origin, timestamp information, message expiration (if content is time-sensitive), message identifier, correlation identifier, return address, etc., and&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Body&lt;/i&gt;: &amp;nbsp;the data content that the receiver is looking to use.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When sending a message, the sender intends for the message to be used, or responded to, in a particular way. &amp;nbsp;The intention of the message may be described as being one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Command Message&lt;/i&gt;: &amp;nbsp;invokes a procedure in another application,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Document Message&lt;/i&gt;: &amp;nbsp;passes a set of data to another application,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event Message&lt;/i&gt;: &amp;nbsp;notifies another application of a change in state, and&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Request-Reply&lt;/i&gt;: &amp;nbsp;requests a reply from another application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Event messages deserve a bit more discussion. &amp;nbsp;In its simplest form, an event message would simply be informational, letting subscribers know that an event has occurred; e.g., a new laser scan is available. &amp;nbsp;If subscribers would like details concerning the event, they would send a request-reply to the sender of the event to provide further details; e.g., the laser scan details. &amp;nbsp;Alternatively, the event could be a document &lt;i&gt;as&lt;/i&gt;&amp;nbsp;an event to inform subscribers that an event has occurred along with the details of that event; e.g., a new laser scan is available with laser scan details included. &amp;nbsp;The size of the event details and the rapidity in which the event occurs should be considered when deciding between publishing simple event messages and document messages &lt;i&gt;as&lt;/i&gt; events.&lt;/p&gt;
&lt;p&gt;Request-reply messages could also use a bit more describing. &amp;nbsp;A request-reply is usually implemented as two point-to-point channels. &amp;nbsp;The first channel delivers the request as a command message, while the second carries the reply back to the requestor as a document message. &amp;nbsp;To keep the replying component more loosely coupled and reusable, the requestor should include a &lt;i&gt;return address&lt;/i&gt;&amp;nbsp;indicating the channel that the replier should use to publish the reply. &amp;nbsp;After receiving the reply, a challenge for the requestor is to then correlate the reply to the original request. &amp;nbsp;If the requestor is sending a number of requests in succession, it will likely be difficult to keep clear &amp;ndash; if it matters &amp;ndash; which request a reply is associated with. &amp;nbsp;To resolve this, every request may include a unique &lt;i&gt;message identifier&lt;/i&gt;&amp;nbsp;that the replier would then include as a &lt;i&gt;correlation identifier&lt;/i&gt;. &amp;nbsp;(A message could have both a message Id and a correlation Id.) &amp;nbsp;The requestor uses the correlation identifier to &amp;ldquo;jog its memory&amp;rdquo; concerning which request the response is for. &amp;nbsp;But frequently, a request-reply is in context of a particular domain object, such as a terrain map or a bank transaction; but the correlation Id doesn&amp;rsquo;t include such information. &amp;nbsp;To assist, the requestor can maintain a mapping (e.g., hashtable) between message Ids and relevant domain object Ids which are related to the original request. &amp;nbsp;When the reply is received, the mapping may be used to load the appropriate domain objects and take further action, accordingly.&lt;/p&gt;
&lt;p&gt;Obviously, it is important that the senders and receivers of a message system agree upon the format that messages will take for clear interoperability, better reusability of components, and extensibility of the system. &amp;nbsp;Consequently, a &lt;i&gt;canonical data model&lt;/i&gt;&amp;nbsp;should be well defined that all applications will adhere to. &amp;nbsp;The canonical data model does not dictate how each application&amp;#39;s domain model must be structured, only how each application must format data within messages. &amp;nbsp;&lt;i&gt;Message translators&lt;/i&gt;&amp;nbsp;are developed to convert the sending application&amp;#39;s domain model into the canonical data model before sending a message; receivers of messages then use their own message translators to translate the message into their own domain. &amp;nbsp;This mechanism allows applications built on completely different technologies (e.g., C#, Lisp, and C++) to communicate with each other and exchange data. &amp;nbsp;Many off the shelf messaging systems define their canonical data model which must be adhered to. &amp;nbsp;For example, the &lt;a href="http://www.ros.org/wiki/"&gt;Robot Operating System&lt;/a&gt; (ROS), which we&amp;#39;ll looking at in more detail in subsequent posts, defines their canonical model at &lt;a href="http://www.ros.org/wiki/msg"&gt;http://www.ros.org/wiki/msg&lt;/a&gt;. &amp;nbsp;But the canonical data model need not be limited to defining the types of primitives available and how to include them in messages.&lt;/p&gt;
&lt;p&gt;Domain-specific canonical data models may augment message formatting rules, adding semantic meaning to the data within a message. &amp;nbsp;For example, the &lt;a href="http://en.wikipedia.org/wiki/JAUS"&gt;Joint Architecture For Unmanned Systems (JAUS)&lt;/a&gt; is a set of message guidelines for the domain of unmanned systems, such as autonomous vehicles. &amp;nbsp;The JAUS guidelines provide domain specific rules for communicating data, such as propulsion and braking commands, sensor events, pose and location information, etc. &amp;nbsp;To demonstrate, JAUS message types include (Siciliano, 2008):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Command&lt;/i&gt;: &amp;nbsp;initiate mode changes or actions,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Query&lt;/i&gt;: &amp;nbsp;used to solicit information from a component,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Inform&lt;/i&gt;: &amp;nbsp;response to a query,&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event set up&lt;/i&gt;: &amp;nbsp;passes parameters to set up an event, and&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event notification&lt;/i&gt;: &amp;nbsp;sent when the event happens.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A challenge in dealing with canonical data models is how to handle changes to the model. &amp;nbsp;In order to support backwards compatibility of existing components when the canonical data model changes, new message channels could be created to carry the messages adhering to the model; e.g., &amp;quot;Perception/LaserScans_V1&amp;quot; and &amp;quot;Perception/LaserScans_V2.&amp;quot; &amp;nbsp;Alternatively, the existing channels could continue to be leveraged to carry messages adhering to different version of the canonical data model. &amp;nbsp;To do so, the message, within its header, would include a &lt;i&gt;format indicator&lt;/i&gt;, such as a version number or format document (e.g., DTD) reference. &amp;nbsp;But if a sender knows that receivers of a particular message are mixed in what format is being used, a component would need to send two messages, one for each version of the canonical data model. &amp;nbsp;Certainly, this is an important consideration when deciding which components should (or even can) be upgraded to newer formats, and in what order.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Routers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While the heavy lifting of the message routing is handled by the messaging middleware itself, there are times when it is useful to augment the middleware with custom message routers to support unique scenarios.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/MessageRouter.png" style="border:0;float:right;margin-left:2px;margin-right:2px;" alt="" /&gt;Suppose the destination of a message may change based on the number of messages that have already passed over a channel. &amp;nbsp;In this scenario, the sender of a message may not know how many messages have been passed over a channel since other senders may have been publishing messages on the same channel. &amp;nbsp;Consequently, a message router may subscribe to the channel to determine where each message should be forwarded to, based on the described business rules. &amp;nbsp;Once the destination is determined, the router would then place the message on a subsequent channel to be delivered to the appropriate destination. &amp;nbsp;This intermediary routing is described as &lt;i&gt;predictive routing&lt;/i&gt;&amp;nbsp;as the message router is aware of every possible destination and the rules for routing, accordingly. &amp;nbsp;If the routing is based on content within the message itself, such as threshold values, then the custom router is known as a &lt;i&gt;content-based router&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;A drawback to using message routers is that if the routing rules change frequently, the message router will need to be modified just as often. &amp;nbsp;To help remedy this, if the rules are expected to change frequently, configurable routing rules (e.g., via XML) could be employed to enable easier management of routing rules.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/MessageFilter.png" style="border:0;float:right;margin-left:2px;margin-right:2px;" alt="" /&gt;Let&amp;#39;s now consider another scenario wherein it&amp;#39;s left up to the subscribers to determine which messages they&amp;#39;re interested in; i.e., subscribers will be responsible for filtering out the messages they&amp;#39;re uninterested in. &amp;nbsp;In this &lt;i&gt;reactive routing&lt;/i&gt; scenario, each subscriber would provide a respective &lt;i&gt;message filter&lt;/i&gt;&amp;nbsp;which is similar to a message router, but simply forwards, or does not forward, a message onto a subsequent channel that the destination subscriber is listening to. &amp;nbsp;Frequently, message filters decide to forward, or not forward, based on content in the message itself; e.g., only forwarding orders that have a coupon included. &amp;nbsp;While being similar to a message router in basic functionality, a message filter only has one possible channel to forward the message onto.&lt;/p&gt;
&lt;p&gt;Deciding between predictive and reactive filtering must take into account a number of considerations. &amp;nbsp;Is the message content sensitive? &amp;nbsp;Do you need to minimize network traffic? &amp;nbsp;Do you need to be able to add and remove subscribers easily? &amp;nbsp;Is the predictive router becoming a bottleneck of message dissemination? &amp;nbsp;For further guidance on selecting among routing options, see (Hohpe, 2003), ppg. 241-242.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Endpoints&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Each messaging middleware option (e.g., CCR, ROS) has unique requirements for communicating with it. &amp;nbsp;Each has its own API, its own means of addressing channels, and its own rules for packaging messages. &amp;nbsp;Ideally, the components of the system should not be aware of the specifics of communicating with the messaging middleware. &amp;nbsp;Furthermore, while unlikely to occur, the middleware should be able to be replaced with another, requiring little, if any, changes to the components. &amp;nbsp;Accordingly, the components must be loosely coupled to the messaging middleware. &amp;nbsp;&lt;i&gt;Message endpoints&lt;/i&gt;&amp;nbsp;provide the bridge between the domain of each component and the API of the messaging middleware.&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin-left:2px;margin-right:2px;" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/MessageEndpoints.png" border="0" alt="" /&gt;Message endpoints are similar in nature to &lt;a href="http://domaindrivendesign.org/node/123"&gt;repositories&lt;/a&gt; when communicating with a database. &amp;nbsp;Repositories encapsulate the code required to communicate with a database to store and retrieve data while being able to convert information from the database into domain objects. &amp;nbsp;If the database changes, or if the mechanism for database communication changes (e.g., ADO.NET to NHibernate), then, ideally, only the repositories are affected. &amp;nbsp;The rest of the application knows little about database communications outside of the repository interfaces. &amp;nbsp;Likewise, components of a message-based system should not be aware of messaging details outside of the message endpoint interfaces, which provide the means to send and receive data. &amp;nbsp;The message endpoint accepts a command or data, converts it into a message, and publishes it onto the correct channel. &amp;nbsp;Additionally, the message endpoint receives messages from a channel, converts the content into the domain of the component, and passes the domain objects to the component for further action. &amp;nbsp;Internally, the message endpoint implements a &lt;i&gt;message mapper&lt;/i&gt; to convert between the component domain objects and the canonical data model.&lt;/p&gt;
&lt;p&gt;While posting to a channel is rather straight forward, a message endpoint may receive a message by acting as a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Polling Consumer&lt;/i&gt;: &amp;nbsp;wherein the receiver looks at a channel on a regular basis for new messages and/or as soon as it completes the processing of a previous message. &amp;nbsp;This frees the receiver from having to deal with messages as soon as they arrive on the channel in favor of dealing with messages went it&amp;rsquo;s ready and willing. &amp;nbsp;A consideration to keep in mind is that messages may queue up on a channel while waiting to be retrieved by the polling consumer. &amp;nbsp;Additionally, a polling consumer may take up threads and resources while polling a channel, even if the channel is empty.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Event-Driven Consumer&lt;/i&gt;: &amp;nbsp;wherein the message is given to the receiver as soon as it arrives on the channel. &amp;nbsp;The benefits to this include avoiding messages queuing up while being able to process messages asynchronously. &amp;nbsp;But the receiver is no longer in control of the timing in which it processes messages and must handle messages as soon as they arrive on a channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many messaging middleware solutions include support for transactions that the message endpoints may leverage, making the endpoints &lt;i&gt;transactional clients&lt;/i&gt;. &amp;nbsp;To illustrate the need for this, suppose the receiver of a request-reply command crashes just moments after the command message is consumed and removed from the channel. &amp;nbsp;When it recovers, the command message is lost and the sender will never receive a reply. &amp;nbsp;Using a transaction, the command message is not removed from the channel until the response is completed and sent. &amp;nbsp;Committing the transaction removes the command message from the channel and adds the reply document message to the reply channel.&lt;/p&gt;
&lt;p&gt;There are a few recommendations which should be considered when developing message endpoints. &amp;nbsp;In accordance with the &lt;a href="http://www.objectmentor.com/resources/articles/srp.pdf"&gt;SRP&lt;/a&gt;, message endpoints should be able to receive messages or send messages, but not both in the same message endpoint. &amp;nbsp;Furthermore, a message endpoint should only communicate with one message channel. &amp;nbsp;If a component needs to send a message on separate channels, it would leverage multiple message endpoints to do so. &amp;nbsp;If your components are developed in line with &lt;a href="http://www.infoq.com/minibooks/domain-driven-design-quickly"&gt;DDD&lt;/a&gt;, it would be each component&amp;#39;s &lt;a href="http://martinfowler.com/eaaCatalog/serviceLayer.html"&gt;application services layer&lt;/a&gt; which would communicate with the message endpoints, preferably via their interfaces instead of concrete instances. &amp;nbsp;This facilitates swapping out the message endpoints with mock objects for unit testing. &amp;nbsp;Leveraging &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2008/10/30/refactoring-service-dependencies-to-separated-interface.aspx"&gt;separated interfaces&lt;/a&gt;&amp;nbsp;and &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2009/11/09/dependency-injection-101.aspx"&gt;dependency injection&lt;/a&gt;&amp;nbsp;helps enable this approach. &amp;nbsp;While these guidelines introduce more objects and indirection, they are proven practices for increasing maintainability of the component and reusability of the message endpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Performance of Message Based Systems&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One would likely be quick to assume that developing a message-based system has a huge cost to performance. &amp;nbsp;Domain objects are converted to messages, messages are passed over channels, routers and filters intercept and forward messages, and messages are converted back into domain objects...this sounds like a heck of a lot going on. &amp;nbsp;But because each component executes in its own thread or process, they need not wait for other components to complete their job before being able to move on to handling another message or task.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/SynchVsAsynchProcessing.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;In the figure above (adapted from&amp;nbsp;Hohpe, 2003, pg. 73), note that a sequential process requires that each message life cycle is completed in full before moving on to the next message. &amp;nbsp;But in an asynchronous, message-based system, each component can move onto a subsequent message just as soon as it has completed its part in the last one. &amp;nbsp;This greatly compensates for the extra overhead imparted by the messaging infrastructure.&lt;/p&gt;
&lt;p&gt;With that said, there are some component responsibilities which take a long time to complete and may impede the speed by which messages are processed. &amp;nbsp;For example, imagine a component which takes images from a web cam and extracts information such as human figures or road signs. &amp;nbsp;This is likely a time consuming process and would impact the turn around time in which the component could process subsequent messages. &amp;nbsp;To alleviate this bottleneck, multiple instances of the same component may subscribe to the same point-to-point channel. &amp;nbsp;Recall that a point-to-point channel ensures that each message only has a single receiver. &amp;nbsp;The instances of the component then become &lt;i&gt;competing consumers&lt;/i&gt; of each message. &amp;nbsp;So if one instance of the component is still processing an earlier message, another instance can grab the next message that arrives for concurrent processing. &amp;nbsp;Power in numbers!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monitoring and Debugging&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Due to the widely asynchronous nature of message-based systems, attention must be given to monitoring and debugging techniques to observe system behavior and iron out problems.&lt;/p&gt;
&lt;p&gt;Logging message content is an invaluable measure towards getting a clear look at what communications are taking place. &amp;nbsp;To facilitate this, logging could be added directly into sending and receiving components, but logging message content should not be a concern of components; accordingly, using a monitoring utility to log such information is a cleaner separation of concerns. &amp;nbsp;Certainly a benefit of publish-subscribe channels is that a monitoring component may subscribe to all messages and log the information to a file or console window. &amp;nbsp;While it&amp;rsquo;s just as valuable to monitor messages on point-to-point channels, if a monitor were to consume a message over a point-to-point channel, the message would be noted as consumed and would no longer be available to the intended receiver. &amp;nbsp;Because such monitoring capability is so helpful in developing and debugging, many messaging middleware options include a &amp;quot;peek&amp;quot; option which allows a monitoring utility to review message contents on a point-to-point channel without actually consuming the message. &amp;nbsp;This capability should be taken into consideration when comparing messaging middleware alternatives.&lt;/p&gt;
&lt;p&gt;In addition to monitoring message content sent over channels, it&amp;rsquo;s also assistive to monitor active subscriptions to various channels to accurately determine which components are receiving which messages. &amp;nbsp;This capability is typically built into messaging middleware solutions and is very assistive during development.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s possible that even if a message is routed appropriately, the receiving component may not know what to do with the message due to an incorrectly formatted header or body content. &amp;nbsp;Invalid messages such as this should be forwarded to an &lt;i&gt;invalid message channel&lt;/i&gt; which an error logging utility would monitor and log, accordingly. &amp;nbsp;An invalid message channel is setup just like any other channel but with the intention of exposing such messages for debugging purposes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Closing Thoughts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Developing asynchronous, message-based systems requires a paradigm shift from the more traditional, synchronously executed applications that most people are familiar with. &amp;nbsp;It is not appropriate for every application domain and should be seen as one additional architectural option to consider when developing applications. &amp;nbsp;But in some domains, such as robotics or in the integration of disparate applications, this approach to development is absolutely pivotal in providing responsive behavior without sacrificing maintainability of the overall system. &amp;nbsp;Indeed, by splitting responsibilities into discrete components, loosely coupled to each other via messaging middleware, immensely complex problems can be broken down into understandable chunks while being flexible enough to accommodate changes to the underlying middleware or introduction of new components.&lt;/p&gt;
&lt;p&gt;In the next couple of posts, we&amp;#39;ll look at a checklist for developing message-based systems followed with examples in CCR and ROS.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;br /&gt;&lt;a href="http://wiki.sharparchitecture.net"&gt;http://wiki.sharparchitecture.net&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;P.S., for S#arp fans, we&amp;#39;re trying to get another release together for the coming week...and this ain&amp;#39;t no quarterly release. ;)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hohpe, G., Woolf, B. &amp;nbsp;2003. &amp;nbsp;&lt;a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683"&gt;Enterprise Integration Patterns: &amp;nbsp;Designing, Building, and Deploying Messaging Solutions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Siciliano, B., Khatib, O. &amp;nbsp;2008. &amp;nbsp;&lt;a href="http://www.amazon.com/Springer-Handbook-Robotics-Bruno-Siciliano/dp/354023957X"&gt;Springer Handbook of Robotics&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55589" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Robotics/default.aspx">Robotics</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>Architectural Paradigms of Robotic Control</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2010/02/03/software-architectural-approaches-for-robotics.aspx</link><pubDate>Wed, 03 Feb 2010 22:39:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55261</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;&lt;strong&gt;Introducing a New Blog Series&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Rarely do I make new year&amp;#39;s resolution. &amp;nbsp;But I found myself pinky swearing myself a single resolution for this year: &amp;nbsp;write a series of tractable posts concerning the development of software for robotics. &amp;nbsp;Accordingly, I intend to introduce background, techniques, and examples with respect to the following topics and more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Software Architectural Approaches for Robotics (e.g., Deliberative, Reactive, Hybrid)&lt;/li&gt;
&lt;li&gt;Software Design Methodologies (e.g., for Behavior Based Robotics, for Hierarchical)&lt;/li&gt;
&lt;li&gt;Integration Patterns (Message Channels, Publish/Subscriber, RPC)&lt;/li&gt;
&lt;li&gt;Machine Learning and Adaptation Techniques (Neural Nets, Genetic Algorithms, Fuzzy Logic)&lt;/li&gt;
&lt;li&gt;Planning Algorithms (Discrete Planning, Continuous Spaces, Motion Planning)&lt;/li&gt;
&lt;li&gt;Simultaneous Localization and Mapping Techniques (Kalman Filters, Particle Filters)&lt;/li&gt;
&lt;li&gt;Tools &amp;amp; Frameworks (Microsoft Robotics Studio, Robot Operating System)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#39;m writing this series of posts for two reasons. &amp;nbsp;The first, as always, is to bounce ideas off readers as a sanity check. &amp;nbsp;The second is to instill interest in readers in this rapidly evolving field. &amp;nbsp;The sophistication of software algorithms within robotics is beginning to lag behind the potential capabilities of available hardware. &amp;nbsp;Accordingly, if this series acts as motivational tool to get others involved in tackling the current algorithmic challenges involved in robotics, then all the better.&lt;/p&gt;
&lt;p&gt;To make this series more interesting and applicable to the development audience that reads &lt;a&gt;http://devlicio.us&lt;/a&gt;, I will attempt, when appropriate, to focus on patterns and general techniques that could possibly be applicable to scenarios outside of robotics. &amp;nbsp;Additionally, due to this series&amp;#39; focus on software, I&amp;#39;ll concentrate on leveraging simulators over physical, often expensive, robotics hardware to make it easier for readers to duplicate provided examples.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Introduction to Architectural Paradigms of Robotic Control&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;While &amp;quot;architecture&amp;quot; is likely one of the least definable terms in software development, it is unavoidably a topic which has one of the greatest impacts on the extensibility and maintainability of an application. &amp;nbsp;Indeed, a frequent cause of an application re-write is due to the architectural decisions that were made early in the project, or the lack thereof. &amp;nbsp;Certainly one of the difficulties in instituting proper architectural practices in a project lies in the fact that architectural decisions must carefully be decided at many different levels of project development. &amp;nbsp;Obviously, the architectural decisions at each level should be made in context of the project requirements in order to facilitate a proper balance of speed of development, scalability of development, and maintainability of the application in the future.&lt;/p&gt;
&lt;p&gt;To illustrate, consider a basic eCommerce site vs. a corporate financial management application which integrates with various third party tools. &amp;nbsp;There are two aspects of architecture which must be carefully considered. &amp;nbsp;The first is deciding which project contexts will require architectural consideration. &amp;nbsp;The second is defining the architectural approach to meet the needs of the given project context, and implementing any necessary prefactoring, accordingly.&lt;/p&gt;
&lt;p&gt;For a basic eCommerce site, the project contexts requiring architectural consideration would likely include: &amp;nbsp;appropriate separation between presentation and control, separation between control and the domain, separation between the domain and data access, and appropriate integration with a payment gateway. &amp;nbsp;Perhaps the &lt;a href="http://en.wikipedia.org/wiki/Active_record_pattern"&gt;active record pattern&lt;/a&gt; might be chosen as the data access mechanism. &amp;nbsp;If&amp;nbsp;&lt;a href="http://martinfowler.com/articles/injection.html"&gt;inversion of control&lt;/a&gt;&amp;nbsp;seems overkill for such a small application, perhaps direct communications to the payment gateway via the domain objects might be chosen as the means of integration. &amp;nbsp;Accordingly, &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2006/09/20/Planning-for-vs.-Reacting-to-Change.aspx"&gt;judicious prefactoring&lt;/a&gt; would suggest that an &lt;a href="http://www.agile-architecting.com/Architecture%20Spikes.pdf"&gt;architectural spike&lt;/a&gt; be created demonstrating appropriate use of the active record pattern with a selected tool along with an example of how and where integration with the payment gateway would take place.&lt;/p&gt;
&lt;p&gt;For the more complex and demanding needs of the financial management application, architecture considerations, in addition to those taken into account for the basic eCommerce site, might include: &amp;nbsp;what integration patterns might be leveraged to facilitate client integration, messaging patterns that might facilitate server side integration with third party financial calculators, and where inversion of control is appropriate. &amp;nbsp;Perhaps &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;RESTful services&lt;/a&gt; would be included to provide integration support for clients requiring such capabilities. &amp;nbsp;Messaging via a &lt;a href="http://en.wikipedia.org/wiki/Publish/subscribe"&gt;publish/subscribe&lt;/a&gt; mechanism using a &lt;a href="http://www.eaipatterns.com/DistributionAggregate.html"&gt;composed message processor&lt;/a&gt; might be selected as the ideal means for coordinating data with third party vendors on the server side. &amp;nbsp;Again, proper refactoring, from an architectural perspective would include developing architectural spikes along with the foundational pieces of such an application to provide appropriate guidance for developers assisting with the project.&lt;/p&gt;
&lt;p&gt;Developing software for robotics is no different, in this respect, than developing any other application. &amp;nbsp;One must decide where the key architectural decisions need to be made and then provide adequate decisions and guidance to facilitate development in accordance with those decisions. &amp;nbsp;As stated, these decisions must be made in consideration of the project needs. &amp;nbsp;This post focuses on one project context, the architectural context of determining the overall approach to robotic motor control. &amp;nbsp;We&amp;#39;ll delve into three major architectural approaches to motor control along with highlighting a few specific implementations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deliberative vs. Reactive Robotics&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Certainly the best source of intelligent systems to study and emulate are those found in nature. &amp;nbsp;From the humble ant to the&amp;nbsp;exalted&amp;nbsp;human, evolution has honed a variety of strategies for dealing with the physical world. &amp;nbsp;Accordingly, if we are to create intelligent systems, a good place to start is by emulating the behaviors and responses to stimuli demonstrated by living creatures.&lt;/p&gt;
&lt;p&gt;In the early days of robotics, it was presumed that the most effective approach to emulating intelligence was by taking in detailed measurements provided by sensors, creating an internal representation of the world (e.g., grid-based maps), making plans based on that internal representation, and sending pre-planned commands to &lt;i&gt;actuators&lt;/i&gt; (devices which convert energy into motion) for moving and interacting with the world. &amp;nbsp;Inevitable, this approach presumes that the internal representation of the world is highly accurate, that the sensor reading are precise, and that there is enough time to carry out a plan before the world changes. &amp;nbsp;In other words, this approach is highly &lt;i&gt;deliberative&lt;/i&gt;. &amp;nbsp;Obviously, the world is highly dynamic, sensor readings are sometimes&amp;nbsp;erroneous, and time is sometimes of the&amp;nbsp;essence&amp;nbsp;when interacting with the world. &amp;nbsp;E.g., you probably wouldn&amp;#39;t want to spend much time creating an internal representation of the world if there&amp;#39;s a Mac truck speeding towards you.&lt;/p&gt;
&lt;p&gt;At the other extreme from deliberative is a &lt;i&gt;reactive &lt;/i&gt;approach to interacting with the world. &amp;nbsp;Taking a purely reactive approach does away with plans and internal representations of the world altogether; instead, a reactive approach focuses on using the world as its own model and reacts, accordingly. &amp;nbsp;Instead of plans, reactive approaches often rely upon &lt;a href="http://en.wikipedia.org/wiki/Finite-state_machine"&gt;finite state machines&lt;/a&gt; to modify behavior as the world changes. &amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Rodney_Brooks"&gt;Rodney Brooks&lt;/a&gt; changed robotics thinking upside down when he introduced this paradigm shift in the 80s. &amp;nbsp;The robots he and his team produced were much faster in their reaction times, when compared to deliberative robots, and exhibited surprisingly complex behavior, appearing quite intelligent in many scenarios. &amp;nbsp;But as is any extreme, a purely reactive approach to the world had it&amp;#39;s own drawbacks; its difficulty in managing complex scenarios which demand careful planning is one such example.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/DeliberativeVsReactive.PNG" style="border:0;float:right;" alt="" /&gt;The&amp;nbsp;figure&amp;nbsp;at right illustrates some of the differences between deliberative and reactive systems. &amp;nbsp;Adapted from (Arkin, 1998).&lt;/p&gt;
&lt;p&gt;While there are certainly pros and cons to either approach, there are some scenarios which are appropriate to one or the other. &amp;nbsp;While still others may require more of a hybrid approach. &amp;nbsp;Let&amp;#39;s now take a look at each approach in more detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deliberative/Hierarchical Style&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of the first successful architectural implementations on a mobile robotic platform was the well known robot known as &lt;a href="http://en.wikipedia.org/wiki/Shakey_the_robot"&gt;Shakey&lt;/a&gt;, created at Stanford University in the 1960s. &amp;nbsp;Of particular note was the robot&amp;#39;s architecture which was made up of three predominant layers: &amp;nbsp;a sensing layer, a planning layer, and an execution layer. &amp;nbsp;Accordingly, as information would be made available by sensors, Shakey would make plans on how to react to the perceived world and send those plans on to the execution layer for low level control of actuators. &amp;nbsp;This began the architectural paradigm known as &lt;i&gt;sense-plan-act (SPA)&lt;/i&gt;. &amp;nbsp;As the SPA approach matured, additional layers were introduced in a hierarchical style, typically all of which having access to a global world model. &amp;nbsp;The upper layers in the hierarchy would use the world model to make plans reaching into the future. &amp;nbsp;After plan development completed at the highest levels, the plans would be broken down into smaller commands and passed to lower levels for execution. &amp;nbsp;Lower layers would then further decompose the commands into more actionable tasks which would ultimately be passed on to actuators at the lowest level. &amp;nbsp;In a hierarchical approach, the sensing layers participate in keeping the internal representation of the world updated. &amp;nbsp;Furthermore, to better accommodate dynamic changes to the world environment, lower planning layers may suggest changes to plans based on recent changes to the world model.&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/HierarchicalParadigm.PNG" border="0" alt="" /&gt;The diagram at right roughly illustrates this hierarchical architectural approach. &amp;nbsp;As should be noted, the sensing layers update the world model while a hierarchy of planning and execution layers formulate plans and breaks those plans down into actionable tasks. &amp;nbsp;Adapted from (Kortenkamp, 1998).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/HierarchicalParadigm.PNG"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;4D/RCS&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;The current pinnacle of hierarchical architectures may be found in the reference architecture known as &lt;a href="http://www.isd.mel.nist.gov/documents/albus/4DRCS_ver2.pdf"&gt;4D/RCS (4 Dimensional / Real-time Control System)&lt;/a&gt;. &amp;nbsp;4D/RCS is the latest version of the RCS reference model architecture for intelligent systems that has been evolving for decades. &amp;nbsp;With 4D/RCS, six (more or less) layers are defined for creating and decomposing plans into low level action:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unit/Vehicle/Mission Layer: &amp;nbsp;this layer decomposes the overall plan into actions for individual modules.&amp;nbsp;&amp;nbsp;Plans are regenerated every 2 hours to account for changes to the world model.&lt;/li&gt;
&lt;li&gt;Module Layer: &amp;nbsp;converts actions into tasks to be performed on specific objects and schedules the tasks, accordingly.&amp;nbsp;&amp;nbsp;Plans are regenerated every 10 minutes.&lt;/li&gt;
&lt;li&gt;Task Layer: &amp;nbsp;converts actions on a single object into sequences of moves to carry out the action.&amp;nbsp;&amp;nbsp;Plans are regenerated every minute.&lt;/li&gt;
&lt;li&gt;Elemental Layer: &amp;nbsp;creates plans for each move, avoiding obstacles and collisions. &amp;nbsp;Plans are regenerated every 5 seconds.&lt;/li&gt;
&lt;li&gt;Primitive Layer: &amp;nbsp;determines motion primitives (speed, trajectory) to facilitate smooth movement. &amp;nbsp;Plans are&amp;nbsp;regenerated&amp;nbsp;every 0.5 second.&lt;/li&gt;
&lt;li&gt;Servo Layer: &amp;nbsp;sends servo control commands (velocity, force) to actuators. &amp;nbsp;Plans are&amp;nbsp;regenerated&amp;nbsp;every 0.05 seconds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the heart of each and every layer are one or more 4D/RCS nodes which contain a behavior generation process which accepts commands from the next higher level and issues subgoals to the behavior generation process at lower levels. &amp;nbsp;Furthermore, each node reports its task execution status up the chain for consideration into further planning. &amp;nbsp;While plans are being solidified and disseminated, a sensory processing process in each node receives sensory input from lower levels, updates the world model, and collates the sensory data into larger units which it passes on to the next higher level; e.g., points get converted to lines which get converted to surfaces which get converted to objects with each successive rise through the 4D/RCS layers &amp;nbsp;A &lt;a href="http://upload.wikimedia.org/wikipedia/commons/c/c6/RCS_NODE_Internal_structure.jpg"&gt;visual summary of a 4D/RCS node&lt;/a&gt; quickly shows just how complex such a system can become. &amp;nbsp;But sometimes the demands of a task require a respective amount of sophistication in the architectural approach. &amp;nbsp;&amp;nbsp;A comprehensive review of the 4D/RCS approach is discussed in (Albus, 2006).&lt;/p&gt;
&lt;p&gt;The primary advantage to deliberative, hierarchical approaches such as 4D/RCS is that competent plans for managing complex scenarios can be generated and broken down into smaller chunks for lower levels to execute. &amp;nbsp;But an obvious disadvantage to this comes in the form of much added complexity to the overall system while penalizing the speed at which the system can react to a changing environment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reactive Style&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In the 1980s, Rodney Brooks, in an effort to overcome some of the limitations of sense-plan-act that Shakey and other such robots exhibited, introduced the concept of reactive control. &amp;nbsp;&amp;quot;Simply put, reactive control is a technique for tightly coupling perception and action, typically in the context of motor behaviors, to produce timely robotic response in dynamic and unstructured worlds.&amp;quot; &amp;nbsp;(Arkin, 1998). &amp;nbsp;In other words, by eliminating the reliance on maintaining an internal world model and avoiding large amounts of time generating plans, simple responses can be executed in reaction to specific stimuli, thus exhibiting behavior similar to that of living organisms. &amp;nbsp;If there was any doubt in what Brooks was trying to imply, he boldly titled one of his works,&amp;nbsp;&lt;a href="http://people.csail.mit.edu/brooks/papers/Planning%20is%20Just.pdf"&gt;Planning is Just a Way of Avoiding Figuring Out What to do Next&lt;/a&gt;. &amp;nbsp;This paradigm shift away from planning turned sense-plan-act into a simpler&amp;nbsp;&lt;i&gt;sense-act&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Accordingly, in a sense-act paradigm, the primary focus is in carefully defining behaviors and the environment stimulus which should invoke those behaviors. This focus is deeply rooted in the idea of &lt;a href="http://en.wikipedia.org/wiki/Behaviorism"&gt;behaviorism&lt;/a&gt;;&amp;nbsp;from a behaviorism perspective, behavior is defined in terms of stimulus and response by observing what an organism does. &amp;nbsp;This approach of developing robotics around such behaviors, unsurprisingly enough, is commonly referred to as&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Behavior-based_robotics"&gt;Behavior Based Robotics&lt;/a&gt;. &amp;nbsp;By leveraging simple state machines, which we&amp;#39;ll examine below, to define which behaviors are active for a given stimuli, the overall architectural complexity is greatly reduced while giving rise to responsive, seemingly intelligent behaviors. &amp;nbsp;(The question of whether or not the robot is truly intelligent and/or self-aware is a debate that I&amp;#39;ll leave to others such as &lt;a href="http://en.wikipedia.org/wiki/John_Searle"&gt;Searle&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Daniel_Dennett"&gt;Dennett&lt;/a&gt;.) &amp;nbsp;While the reactive approach took the spotlight for a number of years, and is still very appropriate in some cases, its limitations in managing complex scenarios and performing sophisticated planning indicated that this approach was not the end all panacea for all situations.&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/ReactiveParadigm.PNG" style="border:0;float:right;" alt="" /&gt;The diagram at right clarifies that reactive systems remove planning and deal with sensory input within the context of each behavior. &amp;nbsp;I.e., &amp;quot;Behavior 1&amp;quot; has no knowledge of the feedback coming from &amp;quot;Sensor 3.&amp;quot; &amp;nbsp;Adapted from (Kortenkamp, 1998).&lt;/p&gt;
&lt;p&gt;&lt;i&gt;A Design Methodology for Reactive Systems&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Due to the simplistic nature of reactive systems, the corresponding design methodology for developing such systems is rather straight-forward (Kortenkamp, 1998):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose the tasks to be performed. &amp;nbsp;E.g., find kitchen.&lt;/li&gt;
&lt;li&gt;Break down the tasks in terms of specific motor-behaviors necessary to accomplish each task. &amp;nbsp;E.g., find wall, follow wall, recognize kitchen.&lt;/li&gt;
&lt;li&gt;For each action, find a condition under which each action should be taken. &amp;nbsp;E.g., wall found.&lt;/li&gt;
&lt;li&gt;For each condition, find a set of perceptual measurements that are sufficient to determine the truth of the condition. &amp;nbsp;E.g., long straight line connected to obstacle.&lt;/li&gt;
&lt;li&gt;For each measurement, design a custom sensory process to compute it. &amp;nbsp;E.g., bumper sensor activated, edge length over threshold found.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When implemented, we find that the defined behaviors can be realized as states within a finite state machine and that found conditions act as the mechanism for changing from one behavior state to another. &amp;nbsp;What&amp;#39;s missing is an arbitration mechanism to determine which behavior wins out in light of competing conditions. &amp;nbsp;Let&amp;#39;s briefly look at implementation approaches to reactive systems along with how such arbitration is achieved.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Subsumption &amp;amp;&amp;nbsp;&lt;span style="font-style:normal;"&gt;&lt;i&gt;Motor Schemas&lt;/i&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;A key concern with reactive, behavior based robotics is determining which behavior should take&amp;nbsp;precedence&amp;nbsp;if conditions exist to activate two or more behaviors. &amp;nbsp;An arbitration mechanism needs to be introduced to resolve such competing situation. &amp;nbsp;Brooks dealt with this issue by proposing an architecture known as &lt;/span&gt;&lt;a href="http://ai.eecs.umich.edu/cogarch0/subsump/"&gt;subsumption&lt;/a&gt;&lt;span&gt;. &amp;nbsp;Simply enough, a subsumption architecture still uses a finite state machine to codify behaviors and transitions, but introduces behavioral layers which can provide input to other layers and override behaviors of lower layers. &amp;nbsp;The advantage is in facilitating more sophisticated behaviors as a sum of &amp;quot;lesser&amp;quot; behaviors. &amp;nbsp;It&amp;#39;s better understood by reviewing the following example from (Arkin, 1998):&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;img src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/BehaviorBasedArchitectureExample.gif" border="0" alt="" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the example, there are three behavioral layers: &amp;nbsp;Avoid-Objects, Explore, and Back-Out-of-Tight-Situations. &amp;nbsp;The Avoid-Objects Layer&amp;#39;s responsibility is to avoid objects by moving away from any perceived obstacles. &amp;nbsp;The Explore Layer&amp;#39;s responsibility is to cover large areas of space in the absence of obstacles. &amp;nbsp;The highest level assists the robot in getting out of tight spaces if the lower layers are unable to do so. &amp;nbsp;Each discrete behavior can invoke transitions to other behaviors and/or provide input or advice to subsequent behaviors based on perceived conditions. &amp;nbsp;The &amp;quot;trick&amp;quot; of subsumption is that higher levels can suppress commands between lower level behaviors; consequently, higher layers are able to handle more complex scenarios by manipulating lower level behaviors in addition to its own. &amp;nbsp;To illustrate suppression, note, in the above example that the &amp;quot;Reverse&amp;quot; behavior in the&amp;nbsp;Back-Out-of-Tight-Situations Layer suppresses any commands that the &amp;quot;Forward&amp;quot; behavior is sending to the actuators. &amp;nbsp;By doing so, complex behaviors may emerge using a number of basic behaviors and a relatively simple architectural approach.&lt;/p&gt;
&lt;p&gt;A major challenge in using a subsumption architecture is deciding the appropriate hierarchy of behavioral layers. &amp;nbsp;In more complex scenarios, it quickly gets sticky deciding which layer should have the right to suppress which other layers. &amp;nbsp;(Otherwise known as spaghetti-prone.) &amp;nbsp;Additionally, since the layers have bi-directional dependencies amongst each other, in order to provide input and suppression, changes to layers can have large impacts on other layers, often resulting in shotgun surgery with any change. &amp;nbsp;Ronald Arkin introduced a subsequent architecture to address these, and other concerns, with an approach known as Motor-Schema based control which does away with arbitrating competing behaviors. &amp;nbsp;Each active behavior in a Motor-Schema based control system calculates a vector to be carried out by an actuator (e.g., wheels or arm). &amp;nbsp;Using vector addition, a final vector for each actuator is computed and sent for execution. &amp;nbsp;With this approach, the output of behaviors is combined instead of arbitrated. &amp;nbsp;This avoids the need to determine suppression hierarchies and makes a more extensible application, within the limits of behavior based robotics.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hybrid Style&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img border="0" src="http://devlicious.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/HybridParadigm.PNG" style="border:0;float:right;" alt="" /&gt;Most modern architectural approaches to robotics control attempt to combine the planning capabilities of deliberative systems with the responsiveness of reactive systems. &amp;nbsp;Appropriately enough, this is referred to as a hybrid style. &amp;nbsp;While the deliberative approach takes a sense-plan-act perspective and the reactive approach follows with plan-act, a hybrid approach typically takes the form of &lt;i&gt;plan, sense-act&lt;/i&gt;. &amp;nbsp;So while the sense-act layers carry out behaviors, the deliberative planning layer can observe the progress of reactive behaviors and suggest direction based on reasoning, planning and problem-solving. &amp;nbsp;The diagram at right crudely demonstrates this combination of the two approaches. &amp;nbsp;Adapted from (Kortenkamp, 1998).&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Three-Layer Architecture (3T)&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;James Firby&amp;#39;s thesis proposing Reactive Action Packages (RAPs) (Firby, 1989) provided a solid approach for integrating deliberative planning with reactive behaviors in the form of a three layer architecture. &amp;nbsp;A multitude of subsequent architectures have emulated a similar approach, coming to be known as 3T architecture. &amp;nbsp;From Eran Gat&amp;#39;s essay &lt;i&gt;Three Layer Architecture&lt;/i&gt;&amp;nbsp;(Kortenkamp, 1998):&lt;/p&gt;
&lt;blockquote&gt;Three-layer architectures organize algorithms according to whether they contain no state, contain state&amp;nbsp;reflecting&amp;nbsp;memories about the past, or contain state&amp;nbsp;reflecting&amp;nbsp;predictions about the future. &amp;nbsp;Stateless sensor-based algorithms inhabit the control component. &amp;nbsp;Algorithms that contain memory about the past inhabit the sequencer. &amp;nbsp;Algorithms that make predictions about the future inhabit the deliberator. ... In 3T the components are called the &lt;i&gt;skill layer&lt;/i&gt;, the &lt;i&gt;sequencing layer&lt;/i&gt;, and the &lt;i&gt;planning [deliberative] layer&lt;/i&gt;.&lt;/blockquote&gt;
&lt;p&gt;As implied by being a hybrid approach, this 3T architecture is not mutually exclusive to behavior driven robotics. &amp;nbsp;Indeed, the skill layer itself is made up of unique behaviors which resemble that of reactive systems. &amp;nbsp;The sequencing layer then uses the world model to determine when a change in behavior is required. &amp;nbsp;The planning layer can then monitor the lower layers and perform more deliberative, time consuming processes such as path planning. &amp;nbsp;The primary variation amongst 3T implementations lies in the decision between whether the planning layer &amp;quot;runs the show&amp;quot; or if the sequencing layer takes command and invokes the planning layer only when needed. &amp;nbsp;&lt;a href="http://ai.eecs.umich.edu/cogarch3/Gat/Gat.html"&gt;Atlantis&lt;/a&gt; is one such example that leaves primary control to the sequencing layer to invoke the planning layer. &amp;nbsp;Other examples of 3T implementations include Bonasso&amp;#39;s &lt;i&gt;&lt;a href="http://dli.iiit.ac.in/ijcai/IJCAI-91-VOL2/PDF/089.pdf"&gt;Integrating Reaction Plans and Layered Competences through Synchronous Control&lt;/a&gt;&lt;/i&gt;&amp;nbsp;and &lt;a href="http://cs.stanford.edu/people/petrovsk/dn/publications/montemerlo_fsr08.pdf"&gt;Standford&amp;#39;s Junior&lt;/a&gt; which took 2nd place in &lt;a href="http://www.darpa.mil/grandchallenge/index.asp"&gt;Darpa&amp;#39;s Urban Challenge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wrapping Up&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The intention of this article has been to provide an introductory overview of paradigms of robotic control including deliberative/hierarchical systems, reactive systems, and hybrid systems. &amp;nbsp;While each approach is appropriate in select contexts, a hybrid&amp;nbsp;architecture&amp;nbsp;is very adaptable for accommodating a large variety of robotic control scenarios with sufficient planning and reactive capabilities. &amp;nbsp;The interested reader is encouraged to dig further into the references and links provided to learn more about these various approaches and design methodologies for implementation.&lt;/p&gt;
&lt;p&gt;In the &lt;a href="http://devlicious.com/blogs/billy_mccafferty/archive/2010/03/01/message-based-systems-for-maintainable-asynchronous-development.aspx"&gt;next post&lt;/a&gt;, we will examine messaging strategies to facilitate the communications amongst the layers and components of robotic systems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Albus, J., Madhavan, R., Messina, E. &amp;nbsp;2006. &amp;nbsp;&lt;a href="http://www.amazon.com/Intelligent-Vehicle-Systems-RCS-Approach/dp/1600212603"&gt;Intelligent Vehicle Systems: A 4D/RCS Approach&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Arkin, R. &amp;nbsp;1998. &amp;nbsp;&lt;a href="http://www.amazon.com/Behavior-Based-Robotics-Intelligent-Autonomous-Agents/dp/0262011654"&gt;Behavior Based Robotics&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Firby, J. &amp;nbsp;1989. &amp;nbsp;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.17.9&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;Adaptive Execution in Complex Dynamic Worlds&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Kortenkamp, D., Bonasso, R., Murphy, R. &amp;nbsp;1998. &amp;nbsp;&lt;a href="http://www.amazon.com/Artificial-Intelligence-Mobile-Robots-Successful/dp/0262611376"&gt;Artificial Intelligence and Mobile Robots&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55261" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Robotics/default.aspx">Robotics</category></item><item><title>Dependency Injection 101</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2009/11/09/dependency-injection-101.aspx</link><pubDate>Mon, 09 Nov 2009 22:26:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53587</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>21</slash:comments><description>&lt;p&gt;&lt;i&gt;(It looks like &lt;/i&gt;&lt;a href="http://www.kevinwilliampang.com/"&gt;&lt;i&gt;Kevin Pang&lt;/i&gt;&lt;/a&gt;&lt;i&gt; and I must have seen the same vision this weekend or had a close encounter flashback as he&amp;#39;s concurrently putting together a great series on &lt;/i&gt;&lt;a href="http://www.kevinwilliampang.com/post/Dependency-Injection-For-Dummies.aspx"&gt;&lt;i&gt;Dependency Injection for Dummies&lt;/i&gt;&lt;/a&gt;&lt;i&gt;...be sure to check out his posts for another take on this subject!)&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:large;"&gt;S&lt;/span&gt;imply put, dependency injection is the technique of supplying an object with its service dependency(s) from an external source.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re unfamiliar with dependency injection or just starting down the road of object oriented programming, the above statement might have the same effect as a mathematics book when the author puts forth a new equation that is about to be analyzed. &amp;nbsp;Symptoms may include glassy eyes, nausea, and headaches. &amp;nbsp;But when taken apart, we find that the idea of dependency injection is a much simpler concept than its grandiose title implies, and is a technique that many developers use commonly, quite naturally in many cases, without even knowing it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Encapsulation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The place to start, in understanding the motivations and implementation of dependency injection, is with the basic idea of encapsulation. &amp;nbsp;Crudely explained, &lt;/span&gt;&lt;strong&gt;&lt;i&gt;encapsulation&lt;/i&gt;&lt;/strong&gt;&lt;span&gt; is the art of determining which bits of logic belong together and putting them into discrete objects. &amp;nbsp;This allows the details of the logic to be modified within the encapsulated object without necessarily impacting the objects which use it. &amp;nbsp;Furthermore, encapsulation provides a neat and clean way to package up reusable code to be used by many other objects without introducing code duplication.&lt;/span&gt;&lt;img style="border:0;float:right;margin:5px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/Robot.png" border="0" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;From a real-world perspective, encapsulation is a very useful technique when building a self-aware robot to take over the world. &amp;nbsp;When building any self-aware robot, you need to start with the basics, such as mobility and sensory perception. &amp;nbsp;For example, a robot might have a stereo camera for observing the visible world, sonar sensors for detecting nearby objects around it, and touch sensors to know if it has made contact with the object it&amp;rsquo;s trying to pick up. &amp;nbsp;Just by describing it, we&amp;rsquo;re already starting to imply areas of logic that could be nicely encapsulated: &amp;nbsp;visual perception, sonar object detection, touch feedback, and mobility.&lt;/p&gt;
&lt;p&gt;Assume for a moment that we&amp;rsquo;ll bypass the practice of encapsulation and throw all of the code for these various modules directly into the primary method which uses them, a benign method we&amp;rsquo;ll call &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt;, living in a .NET assembly called CommandAndControl.dll. &amp;nbsp;The code might look something like the following:&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;public class WorldDomination {
   public void TakeOverTheWorld() {
      // Code to open USB connection to use stereo camera
      // Code to process camera images to identify humans

      // Code to open serial port to legs for moving
      // Code to send legs serial commands to move over to location of human

      // Code to generate speech to user; e.g., &amp;quot;All your leaders are belong to us&amp;quot;
   }
}&lt;/pre&gt;
&lt;p&gt;In the code, we see the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method taking on a lot of responsibilities and given explicit knowledge about components which are subject to change when the robot components are upgraded. &amp;nbsp;Some of the responsibilities which we&amp;rsquo;re burdening the method with include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Knowing the stereo camera is connected via USB and how to open a connection to it;&lt;/li&gt;
&lt;li&gt;Knowing how to process camera images to identify humans;&lt;/li&gt;
&lt;li&gt;Knowing that the legs require communications to be sent via a specific serial port;&lt;/li&gt;
&lt;li&gt;Knowing how to send low level communications to the legs as serial commands.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin:5px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/C3PO.png" border="0" alt="" /&gt;So what&amp;rsquo;s the problem you ask? &amp;nbsp;For starters, the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method would likely be a few thousand lines long and would be immensely difficult to maintain. &amp;nbsp;Let&amp;rsquo;s suppose that we upgrade the camera to use a better stereo imaging device which now receives commands wirelessly. &amp;nbsp;You&amp;rsquo;d have to carefully, tediously walk through all of the lines of &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; to find any communications with the camera, upgrade the capabilities, and test, accordingly. &amp;nbsp;But now testing is much more challenging as well. &amp;nbsp;Since all of the other code, such as the mobility code, will also run whenever we invoke &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt;, then we&amp;rsquo;ll need to make sure that the rest of the robot is in perfect working order while we switch out one component. &amp;nbsp;In other words, it&amp;rsquo;s simply not possible now to test the various components in isolation of each other. &amp;nbsp;This approach quickly turns into spaghetti code, becoming a maintenance nightmare, difficult to debug, and exhibiting decreasing code quality as time progresses. &amp;nbsp;What started out as a simple project to develop a robot to conquer the world is turning out to be about as effective as C-3PO&amp;hellip;after being blasted by a storm trooper that is.&lt;/p&gt;
&lt;p&gt;The first step that we can take, to make our robot for world domination a little easier to understand and maintain, is to encapsulate the various modules into their own, respective classes. &amp;nbsp;Let&amp;rsquo;s look at the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; code again with a sprinkling of better encapsulation by moving the camera related responsibilities to a class called &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;StereoCamera.cs&lt;/span&gt; and the mobility related responsibilities to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;MobilePlatform.cs&lt;/span&gt;. &amp;nbsp;Furthermore, let&amp;rsquo;s move these two classes to a new class library assembly called Services.dll.&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;// Within the Services package (or class library)

public class StereoCamera {
   public void Connect() {
      // Code to open USB connection to use stereo camera
   }

   public MeaslyHuman IdentifyHumanInFieldOfVision() {
      // Code to process camera images to identify humans
   }
}

public class MobilePlatform {
   public void Connect() {
      // Code to open serial port to legs for moving
   }

   public void MoveTo(Location location) {
      // Code to send legs serial commands to move over to location 
   }
}

// Within the CommandAndControl package

public class WorldDomination {
   public void TakeOverTheWorld() {
      StereoCamera camera = new StereoCamera();
      camera.Open();
      MeaslyHuman human = camera.IdentifyHumanInFieldOfVision();

      MobilePlatform legs = new MobilePlatform();
      legs.Connect();
      legs.MoveTo(human.Location);

      // Code to generate speech to user; e.g., &amp;ldquo;All your leaders are belong to us&amp;rdquo;
   }
}&lt;/pre&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin:5px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/DI_5F00_RefactorToPackages.png" border="0" alt="" /&gt;As demonstrated, we introduced two new classes, &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;StereoCamera&lt;/span&gt; and &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;MobilePlatform&lt;/span&gt;, and moved the related responsibilities to those classes. &amp;nbsp;We also introduced a new package as a new class library, called Services.dll, to contain the two new classes. &amp;nbsp;The package diagram now looks as the figure shown to the right.&lt;/p&gt;
&lt;p&gt;This basic refactoring has resulted in a number of benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are far fewer lines of code in the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method and easier to digest for whomever may be looking at it next;&lt;/li&gt;
&lt;li&gt;The &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method is now much easier to understand the overall flow of control without getting bogged down in low level details;&lt;/li&gt;
&lt;li&gt;The &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method now knows nothing about the details related to connecting to the camera via the USB connection (other than simply calling Connect), nothing about the mathematics behind processing camera images to identify humans, nor the details of opening a serial port and sending low level serial commands to move from point A to point B; and&lt;/li&gt;
&lt;li&gt;The &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;StereoCamera&lt;/span&gt; and &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;MobilePlatform&lt;/span&gt; classes are now quite reusable from a variety of other objects that will surely need to use them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall, this encapsulation refactoring has led to a design that is easier to maintain and will likely reflect in the general level of maintainability and quality. &amp;nbsp;So things are better, but we still have much to improve. &amp;nbsp;I suppose we&amp;rsquo;re beginning to resemble C-3PO, but only after Chewbacca put his head on backwards. &amp;nbsp;(OK, so C-3PO didn&amp;rsquo;t have diabolical plans for world dominion, but let&amp;rsquo;s ignore that subtlety for now.) &amp;nbsp;As we proceed, we&amp;rsquo;ll examine what other areas we&amp;rsquo;ll want to improve and learn a bit more about the definition of dependency injection along the way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Services&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Earlier, we defined dependency injection as the technique of supplying an object with its service dependency(s)&amp;hellip; &amp;nbsp;What exactly is a service dependency? &amp;nbsp;A &lt;strong&gt;&lt;i&gt;service&lt;/i&gt;&lt;/strong&gt;, in the context of dependency injection, is any object which provides access to an external resource. &amp;nbsp;In the refactoring exercise we performed on our code, and as implied by the package diagram, two services were introduced. &amp;nbsp;The first provided access to the stereo camera; the second provided access to the legs for moving the robot around. &amp;nbsp;In your own project, services may include web services, data access objects, file manipulation utilities, third party APIs, and many others.&lt;/p&gt;
&lt;p&gt;Because services depend on external resources (e.g., a physical component or database), they are inherently more complicated to test, require that the external resource be available when we test our code, and are subject to change when the underlying resource being managed changes (e.g., when the component is upgraded). &amp;nbsp;When considering these arguments, we want to remain &lt;i&gt;&lt;strong&gt;loosely coupled&lt;/strong&gt;&lt;/i&gt; to the services themselves. &amp;nbsp;To contrast, the refactored code above, even after applying encapsulation, is &lt;strong&gt;&lt;i&gt;tightly coupled&lt;/i&gt;&lt;/strong&gt; to the underlying services.&lt;/p&gt;
&lt;p&gt;To illustrate the idea of tight coupling, the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method is creating each service directly with the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;new&lt;/span&gt; keyword; i.e., the method is creating a concrete instance of the service class. &amp;nbsp;Not only does the method have a concrete dependency on the service class itself, this inherently implies that the application layer that the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class resides in must have a direct dependency on the layer which the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;StereoCamera&lt;/span&gt; service class resides in. &amp;nbsp;This layer dependency is shown as a directional line in the above package diagram from the CommandAndControl layer to the Services layer.&lt;/p&gt;
&lt;p&gt;In addition to having a concrete dependency on the service itself, the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method must also know to call &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;Open&lt;/span&gt; for the respective services (and presumably &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;Close&lt;/span&gt;); i.e., the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method needs to know how to create and initialize the services before it&amp;rsquo;s even able to use them. &amp;nbsp;These are further responsibilities which this method should not be concerned with.&lt;/p&gt;
&lt;p&gt;Ideally, the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method would be loosely coupled to the underlying services and wouldn&amp;rsquo;t have to know about such low level details of the service itself outside of calling methods such as &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;IdentifyHumanInFieldOfVision&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Coding to Interface&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The first step we can take towards making &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; less tightly coupled to the service classes is to have the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method code to the interfaces of the services rather than to the concrete classes themselves. &amp;nbsp;One might argue against introducing two new interfaces for the objects; as we add new objects, we inherently introduce additional complexity to the overall system. &amp;nbsp;Also, with interfaces, not only are we introducing a small amount of additional complexity to the overall system, but we&amp;rsquo;re also introducing indirection. &amp;nbsp;In other words, in order for someone to fully understand what&amp;rsquo;s going on at runtime, the developer will need to determine which concrete object is being used under the interface. &amp;nbsp;It shouldn&amp;rsquo;t be difficult to do so, but it does add time to understanding the overall system. &amp;nbsp;These are fair arguments and ones not to be ignored. &amp;nbsp;Whenever we are faced with a decision that will lead to a better design at the expense of added complexity, we carefully need to consider if the benefits of refactoring outweigh the penalties of added complexity. &amp;nbsp;In this case, coding to interface (and another refactoring we will do next) will lead to a more maintainable system, provide a means to readily unit test the various components in isolation, and will result in a more loosely coupled design.&lt;/p&gt;
&lt;p&gt;Accordingly, we simply need to add two interfaces to the Services package, have the service classes implement them, and change the references in the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method to invoke the interfaces rather than the classes themselves. &amp;nbsp;But as we&amp;rsquo;ll see, this next refactoring still leaves us tightly coupled to the service classes. &amp;nbsp;Let&amp;rsquo;s look at the code.&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;// Within the Services package

public interface IStereoCamera {
   void Connect();
   MeaslyHuman IdentifyHumanInFieldOfVision();
}

public interface IMobilePlatform {
   void Connect();
   void MoveTo(Location location);
}

public class StereoCamera : IStereoCamera {
   public void Connect() {
      // Code to open USB connection to use stereo camera
   }

   public MeaslyHuman IdentifyHumanInFieldOfVision() {
      // Code to process camera images to identify humans
   }
}

public class MobilePlatform : IMobilePlatform {
   public void Connect() {
      // Code to open serial port to legs for moving
   }

   public void MoveTo(Location location) {
      // Code to send legs serial commands to move over to location 
   }
}

// Within the CommandAndControl package

public class WorldDomination {
   public WorldDomination() {
      camera = new StereoCamera();
      legs = new MobilePlatform();
   }

   public void TakeOverTheWorld() {
      camera.Open();
      MeaslyHuman human = camera.IdentifyHumanInFieldOfVision();

      legs.Connect();
      legs.MoveTo(human.Location);

      // Code to generate speech to user; e.g., &amp;ldquo;All your leaders are belong to us&amp;rdquo;
   }

   private readonly IStereoCamera camera;
   private readonly IMobilePlatform legs;
}&lt;/pre&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin:5px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/DI_5F00_AddInterfaces.png" border="0" alt="" /&gt;In the code above, note that the two interfaces were introduced and now the constructor of the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class now handles creating the service instances and setting private members, represented as interfaces, to the service instances. &amp;nbsp;The package diagram reflecting this refactoring is shown at right.&lt;/p&gt;
&lt;p&gt;Even though the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;TakeOverTheWorld&lt;/span&gt; method is now communicating with the interfaces of the services, the class containing is still tightly coupled to the service classes due to the local instantiation of the classes within its constructor. &amp;nbsp;To further alleviate this coupling, we&amp;rsquo;re going to have to move a step &amp;ldquo;up&amp;rdquo; and introduce a package which will be responsible for creating the service dependencies and injecting them into the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class. &amp;nbsp;Yes, we&amp;rsquo;re finally ready to see dependency injection in action.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service Initialization and Injection&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin:5px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/DI_5F00_RefactorToDI.png" border="0" alt="" /&gt;While the previous refactorings have taken us closer towards a more loosely coupled design, we still need to remove the object creation from the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class altogether. &amp;nbsp;By introducing a new package which will contain the robot system&amp;rsquo;s &amp;ldquo;main&amp;rdquo; program, we can leverage that layer to also initialize the service dependencies and inject them into the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class. &amp;nbsp;Let&amp;rsquo;s look at the code of the new package, called Robot, along with modifications to the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class. &amp;nbsp;(The Services package, and the interfaces and classes therein, will remain unchanged.) &amp;nbsp;But before looking at the code, study the package diagram at right to see where the classes live and take particular note of the direction of package dependencies. &amp;nbsp;There&amp;rsquo;s one dependency that&amp;rsquo;s still problematic, which we&amp;rsquo;ll discuss after the code.&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;// Within the CommandAndControl package

public class WorldDomination {
   public WorldDomination(IStereoCamera camera, IMobilePlatform legs) {
      this.camera = camera;
      this.legs = legs;
   }

   public void TakeOverTheWorld() {
      // Same as before
   }

   private readonly IStereoCamera camera;
   private readonly IMobilePlatform legs;
}

// Within the new Robot package

public class Program {
   // This is the &amp;ldquo;main&amp;rdquo; method of the entire robot application.
   // I.e., it&amp;rsquo;s the method that gets called to kick off the application.
   public void Main() {
      IStereoCamera camera = new StereoCamera();
      IMobilePlatform legs = new MobilePlatform();

      WorldDomination worldDomination = new WorldDomination(camera, legs);

      worldDomination.TakeOverTheWorld();
   }
}&lt;/pre&gt;
&lt;p&gt;In the code above, the Main method initializes the services and &amp;ldquo;injects&amp;rdquo; them into the constructor of the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class. &amp;nbsp;As you can see, the injection of service dependencies into a class is really nothing more than passing the service instances as arguments to the class instantiation. &amp;nbsp;So when it comes right down to it, the intimidating phrase &amp;ldquo;dependency injection&amp;rdquo; is really quite simple in practice. &amp;nbsp;But there&amp;rsquo;s still a problem in our implementation that could lead to design &amp;ldquo;rot&amp;rdquo; over time. &amp;nbsp;The CommandAndControl package still has a dependency on the Services package. &amp;nbsp;This is bad because during later phases of the project, without a high level of discipline, developers may forego injecting the service dependencies into the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class, or other classes in the CommandAndControl package and simply instantiate the service classes directly using the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;new&lt;/span&gt; keyword. &amp;nbsp;This would make all the work we&amp;rsquo;ve done to this point to support dependency injection a moot point. &amp;nbsp;To enforce our design, we need to introduce a new pattern known as &lt;strong&gt;&lt;i&gt;dependency inversion&lt;/i&gt;&lt;/strong&gt;, also known as &lt;strong&gt;&lt;i&gt;separated interface&lt;/i&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separated Interface&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin:5px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/DI_5F00_RefactorToSeparatedInterface.png" border="0" alt="" /&gt;To enforce our design, and to eliminate the package dependency from CommandAndControl to Services, we will move the service interfaces to the CommandAndControl package and reverse, or invert, the dependency direction between the two packages. &amp;nbsp; Accordingly, the refactoring steps to do this include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Copy the service interfaces from the Services package to the CommandAndControl package.&lt;/li&gt;
&lt;li&gt;Change the interface references in the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class to refer to the interfaces now found within the CommandAndControl package.&lt;/li&gt;
&lt;li&gt;Remove the package dependency from CommandAndControl to Services. &amp;nbsp;Now add a package dependency from Services to CommandAndControl. &amp;nbsp;(In C#, this would be a matter of deleting the assembly reference from the CommandAndControl class library and adding a new assembly reference from the Services class library.)&lt;/li&gt;
&lt;li&gt;Modify the service classes, StereoCamera and MobilePlatform, to implement the interfaces now found in the CommandAndControl package.&lt;/li&gt;
&lt;li&gt;Modify the Main method, in the Main class to use the interfaces found within the CommandAndControl class.&lt;/li&gt;
&lt;li&gt;Delete the obsolete interfaces from the Services package.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With the &lt;strong&gt;&lt;i&gt;separated interface&lt;/i&gt;&lt;/strong&gt; pattern implemented, the CommandAndControl package is only aware of the service interfaces without having any dependency, whatsoever, on the service implementations. &amp;nbsp;As performed in the previous refactoring, the CommandAndControl package, the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class specifically, is being given its service dependencies via &lt;strong&gt;&lt;i&gt;constructor injection&lt;/i&gt;&lt;/strong&gt; via initialization code found in the Robot&amp;rsquo;s main method.&lt;/p&gt;
&lt;p&gt;With this, we have implemented a basic example, including all the required pieces, for performing dependency injection. &amp;nbsp;It introduced a number of new pieces to the overall application, but our design is now loosely coupled to the underlying services and enables us easily swap out services with new implementations, without having to recompile the CommandAndControl package, and provides the ability for &lt;strong&gt;&lt;i&gt;test doubles&lt;/i&gt;&lt;/strong&gt;, such as mocks, stubs, and fakes, to be injected into the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class when unit testing. &amp;nbsp; (Unit testing with test doubles is beyond the scope of this article, but I encourage you to read &lt;a href="http://xunitpatterns.com/Test%20Double.html"&gt;http://xunitpatterns.com/Test%20Double.html &lt;/a&gt;to begin learning more about this subject.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dependency Injection / Inversion of Control (IoC) Containers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s one final topic which is appropriate to discuss when describing dependency injection: &amp;nbsp;IoC containers. &amp;nbsp;(Dependency injection is also known as &amp;ldquo;Inversion of Control,&amp;rdquo; as originally described by Robert Martin. &amp;nbsp;Interestingly enough, the development community typically uses the phrase &amp;ldquo;dependency injection&amp;rdquo; when talking about the technique itself and &amp;ldquo;IoC&amp;rdquo; when talking about dependency injection containers. &amp;nbsp;But rest assured, there is no difference whatsoever between &amp;ldquo;Dependency Injection&amp;rdquo; and &amp;ldquo;Inversion of Control (IoC).&amp;rdquo;) &amp;nbsp;An IoC Container is a utility which is leveraged to initialize and inject dependencies into the objects that use them. &amp;nbsp;While it is a bit more difficult to visualize than the &amp;ldquo;manual&amp;rdquo; dependency injection we performed in the previous refactoring step, an IoC Container is nothing more than an object factory which initializes an object and satisfies its service dependencies in the process.&lt;/p&gt;
&lt;p&gt;With most IoC Containers (e.g., Ninject, Castle Windsor, LinFu, and many others), there are only a couple of steps required to setup and use the IoC Container:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Register all of the classes which may be injected into another object. &amp;nbsp;In our carefree efforts for world domination via our robot, this would include, at minimum, registering the service classes MobilePlatform and StereoCamera. &amp;nbsp;While each IoC Container has its own means of registering a class for later retrieval, the underlying mechanism is often as simple as adding the service class&amp;rsquo; object type to a hashtable for later lookup. &amp;nbsp; If we were using Castle Windsor with our project, the registration lines would look like the following:
&lt;pre class="c-sharp" name="code"&gt;container.AddComponent(&amp;quot;camera&amp;quot;, 
   typeof(IStereoCamera), typeof(StereoCamera));
container.AddComponent(&amp;quot;mobilePlatform&amp;quot;, 
   typeof(IMobilePlatform), typeof(MobilePlatform));
container.AddComponent(&amp;quot;camera&amp;quot;, typeof(WorldDomination));&lt;/pre&gt;
Note that the last line registers the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class itself.  In doing so, we can let the IoC Container take care of the work of instantiating it with its service dependencies already injected.  We don&amp;rsquo;t &lt;i&gt;have&lt;/i&gt; to hand off instantiation of this class to the IoC Container, but it provides a useful benefit.  Suppose the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class needs a third service dependency provided via its constructor somewhere down the road.  If we aren&amp;rsquo;t using an IoC Container to manage its creation, we&amp;rsquo;d have to look for every place where the class is created, via the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;new&lt;/span&gt; keyword, and pass in the extra dependency.  If we leave its creation to the IoC Container, then we simply add the new service interface parameter to its constructor and the IoC Container will take care of the rest, assuming you&amp;rsquo;ve registered the third dependency  as well.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Invoke the IoC Container to instantiate a registered object with its dependencies already injected. &amp;nbsp; For our project, the following demonstrates getting a handle to the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;, Courier, monospace;"&gt;WorldDomination&lt;/span&gt; class:
&lt;pre class="c-sharp" name="code"&gt;WorldDomination worldDomination = (WorldDomination) 
   ServiceLocator.Current.GetService(typeof(WorldDomination));&lt;/pre&gt;
This line of code tells the IoC Container to return an instance of the requested class with its dependencies injected.  This actually uses an IoC Container known as Common Service Locator.  Since almost all IoC Containers do the same actions &amp;ndash; registering and instantiating objects &amp;ndash; the major IoC Container authors worked together to establish a common interface for all IoC Containers.  In this way, you can register your objects with your favorite IoC Container and then register the IoC Container itself with the Common Service Locator.  It&amp;rsquo;s enough to make your head spin, but leads to further decoupling to the IoC Container itself so that you can easily swap out one for another (e.g., Castle Windsor for Ninject) without modifying the code which depends on the IoC Container.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How you setup and use an IoC Container depends on the environment that you&amp;rsquo;re developing within. &amp;nbsp;For example, if you&amp;rsquo;re developing an ASP.NET MVC application, you can use an IoC Container to instantiate the controllers, injecting their dependencies via the controller&amp;rsquo;s constructor. &amp;nbsp;For example, the following two lines of code, within the Global.asax.cs file, instruct the ASP.NET MVC framework to use Castle Windsor to instantiate controllers:&lt;/p&gt;
&lt;pre class="c-sharp" name="code"&gt;IWindsorContainer container = new WindsorContainer();
ControllerBuilder.Current.SetControllerFactory(
   new WindsorControllerFactory(container));&lt;/pre&gt;
&lt;p&gt;The only thing left is to register the controller dependencies that they require for their constructors and the IoC Container takes care of the rest.&lt;/p&gt;
&lt;p&gt;While this will be enough to gain a basic understanding of what an IoC Container is and how it is used, a bit more studying will be required to learn how to actually set up and use one. &amp;nbsp;For more information about IoC Containers, including examples of setup and usage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Common Service Locator: &amp;nbsp;&lt;a href="http://www.codeplex.com/CommonServiceLocator"&gt;http://www.codeplex.com/CommonServiceLocator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Castle Windsor Tutorial: &amp;nbsp;&lt;a href="http://www.castleproject.org/container/gettingstarted/"&gt;http://www.castleproject.org/container/gettingstarted/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;LinFu in 5 Minutes: &amp;nbsp;&lt;a href="http://www.codeproject.com/KB/cs/LinFu_IOC.aspx"&gt;http://www.codeproject.com/KB/cs/LinFu_IOC.aspx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Using Ninject: &amp;nbsp;&lt;a href="http://ninject.codeplex.com/wikipage?title=user%20guide&amp;amp;ProjectName=ninject"&gt;http://ninject.codeplex.com/wikipage?title=user%20guide&amp;amp;ProjectName=ninject&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;StructureMap: &amp;nbsp;&lt;a href="http://structuremap.sourceforge.net"&gt;http://structuremap.sourceforge.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A classic IoC Overview: &amp;nbsp;&lt;a href="http://martinfowler.com/articles/injection.html"&gt;http://martinfowler.com/articles/injection.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Using IoC in a project: &amp;nbsp;&lt;a href="http://wiki.sharparchitecture.net/"&gt;http://wiki.sharparchitecture.net/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, for a much more thorough analysis of many of the concepts described above, I highly recommend reading Robert Martin&amp;#39;s&amp;nbsp;&lt;a href="http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1257809514&amp;amp;sr=1-1"&gt;Agile Principles, Patterns, and Practices in C#&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="border:0;float:right;margin:5px;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/RobotInvasion.png" border="0" alt="" /&gt;Regardless of whether you&amp;rsquo;re looking to take over the world with a dominion of evil robots or simply trying to build a better web app, dependency injection and the use of an IoC Container can lead to an easy to maintain application that is loosely coupled to service dependencies. &amp;nbsp;These attributes naturally lead to better quality and happier developers. &amp;nbsp;(Both of which I would put squarely into a category known as &amp;ldquo;good.&amp;rdquo;) &amp;nbsp;But while these techniques provide many benefits, they also introduce a bit more complexity; especially when going from &amp;ldquo;manual&amp;rdquo; dependency injection, as we did in the coding example, to the use of an IoC Container. &amp;nbsp;Accordingly, your project team should carefully consider the benefits and added complexity to determine if it&amp;#39;s right for your project. &amp;nbsp;While the use of an IoC Container would be a bit overkill for a very simple application, its use is &lt;i&gt;obviously &lt;/i&gt;pivotal in creating self-aware robotic legions for conquering the world.&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;br /&gt;&lt;a href="http://wiki.sharparchitecture.net/"&gt;http://wiki.sharparchitecture.net/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53587" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>The dojo is open...  www.ITSamuraiSchool.com</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2009/05/18/the-dojo-is-open-www-itsamuraischool-com.aspx</link><pubDate>Mon, 18 May 2009 22:52:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46899</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>11</slash:comments><description>&lt;p&gt;Codai&amp;#39;s IT Samurai School is open for enrollment.&amp;nbsp; It&amp;#39;s Flash, so it&amp;#39;ll take a few moments to download...but I hope you&amp;#39;ll agree it&amp;#39;s worth the wait...&amp;nbsp; &lt;a href="http://www.itsamuraischool.com"&gt;http://www.itsamuraischool.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A few fun facts about the website and the school itself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Born our of a short conversation at a BBQ concerning my desire to do high quality training&lt;/li&gt;
&lt;li&gt;100% Flash front-end, outside of the checkout screens&lt;/li&gt;
&lt;li&gt;Built on latest &lt;a href="http://code.google.com/p/sharp-architecture/"&gt;S#arp Architecture&lt;/a&gt; available from the trunk
&lt;/li&gt;
&lt;li&gt;6 months in the making, including the site and class preparation&lt;/li&gt;
&lt;li&gt;21 classes initially, including ASP.NET MVC, Object-Oriented JavaScript, SQL Server Integration Services, S#arp Architecture and many others&lt;/li&gt;
&lt;li&gt;5 cities initially, including Denver, Austin, San Jose, Washington DC, and Seattle&lt;/li&gt;
&lt;li&gt;A handful of top notch trainers, including myself (IMHO)&lt;/li&gt;
&lt;li&gt;Guest speakers and occasional, one-run only, unique courses&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a title="IT Samurai School" href="http://www.itsamuraischool.com"&gt;&lt;img alt="Codai&amp;#39;s IT Samurai School" style="border:0;" src="http://devlicio.us/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/billy_5F00_mccafferty/dojo_5F00_screenshot.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We look forward to seeing you in class!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=46899" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Quality+Assurance/default.aspx">Quality Assurance</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Project+Management/default.aspx">Project Management</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Test-Driven+Development/default.aspx">Test-Driven Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Agile+Development/default.aspx">Agile Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/MVC.NET/default.aspx">MVC.NET</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Architecture/default.aspx">S#arp Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Tips+_2600_amp_3B00_+Tricks/default.aspx">Tips &amp;amp; Tricks</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category></item><item><title>IT Samurai School coming soon...</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2009/05/03/it-samurai-school-coming-soon.aspx</link><pubDate>Mon, 04 May 2009 02:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:46471</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As if my life wasn&amp;#39;t boring enough trying to get S#arp Architecture 1.0 out the door...&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://www.itsamuraischool.com/"&gt;&lt;img style="border:0;" alt="www.itsamuraischool.com" src="http://devlicio.us/resized-image.ashx/__size/600x450/__key/CommunityServer.Components.UserFiles/00.00.00.21.06/itsamuraischool.gif" width="550" height="347" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=46471" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Algorithms/default.aspx">Algorithms</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Project+Management/default.aspx">Project Management</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Test-Driven+Development/default.aspx">Test-Driven Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Agile+Development/default.aspx">Agile Development</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/MVC.NET/default.aspx">MVC.NET</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Architecture/default.aspx">S#arp Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/DDD/default.aspx">DDD</category></item><item><title>An argument for moving ASP.NET MVC controllers to a separate assembly</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2009/01/09/an-argument-for-moving-asp-net-mvc-controllers-to-a-separate-assembly.aspx</link><pubDate>Fri, 09 Jan 2009 19:21:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:43683</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>24</slash:comments><description>&lt;p&gt;I&amp;#39;d like to buy an argument.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m a proponent of isolating application tiers via separate physical assemblies; e.g., MyProject.Core for domain objects and logic vs. MyProject.Web for views. While I do not encounter much push back with this idea, I seem to raise eyebrows with my desire to move ASP.NET MVC controllers to a separate assembly as well. The result of creating separate, physical assemblies for the logical tiers, including the controllers layer, has a number of benefits.&lt;/p&gt;
&lt;p&gt;The first and primary reason is that it decreases your ability to shoot yourself in the foot.&amp;nbsp; Let me tell a war story to illustrate.&amp;nbsp; About five years ago I was given the privilege to build the most exciting application of my career thus far.&amp;nbsp; In developing it, we tried to emphasize adding complexity and patterns only while refactoring smells and keeping things as simple as possible (which is almost always the best route to take).&amp;nbsp; We didn&amp;#39;t take many &lt;a href="http://www.oreillynet.com/pub/a/network/2005/11/15/what-is-prefactoring.html"&gt;prefactoring&lt;/a&gt; steps and let the system evolve organically.&amp;nbsp; A painfully learned lesson was putting all of the tiers into one physical assembly and separating them only by namespaces and &amp;quot;team agreement.&amp;quot;&amp;nbsp; The major drawback to this was that every layer was technically able to communicate with any other layer, even bi-directionally.&amp;nbsp; (Yes, the most excellent &lt;a href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt; could assist, but what happens when you have to leave a project in another developer&amp;#39;s and/or team&amp;#39;s hands for a while?)&amp;nbsp; Inevitably, bi-directional dependencies began to creep into the code.&amp;nbsp; Progressively, the unit tests, for testing the domain layer, started becoming more and more dependent on an up to date test database and working external services; shortcuts began creeping in to the data layer and external services.&amp;nbsp; Accordingly, the unit tests became slower, more fragile, and tedious to maintain.&amp;nbsp; This bleeding of one layer into another had a few ill effects:&amp;nbsp; developers stopped writing and running unit tests (because they were agonizingly slow to run), the application overall became increasingly difficult to maintain and difficult to make modifications without inadvertently affecting various layers simultaneously, and it became almost impossible to upgrade the data layer without touching all of the layers of the application.&amp;nbsp; Yes, I could have done a lot more to prevent some of these problems, both technically and managerially...but I can&amp;#39;t say I&amp;#39;ve learned as much from any other project as well!&amp;nbsp; (A computer science professor of mine once said that you&amp;#39;re not an expert until you&amp;#39;ve made every mistake in the book...that project almost gave me my expert credentials in one fell swoop.&amp;nbsp; Just kidding, I have plenty more mistakes to make. ;)&lt;br /&gt;&lt;br /&gt;Some of the other benefits of having physically separated tiers come out of this story as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;#39;s helpful for being able to unit test logical tiers in isolation,&lt;/li&gt;
&lt;li&gt;It&amp;#39;s simple to upgrade your data access layer if only the IoC mechanism depends on it directly,&lt;/li&gt;
&lt;li&gt;It&amp;#39;s easier to manage a group of developers which can&amp;#39;t violate the rules when separated assemblies can only depend on each other in one direction, and&lt;/li&gt;
&lt;li&gt;It&amp;#39;s easier to understand (aka - maintain) a tier&amp;#39;s responsibilities which have been physically separated from other tiers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Moral of the story:&amp;nbsp; take necessary prefactoring steps to make applications easier to unit test and maintain...and to make it very hard for you to shoot yourself in the foot!&lt;br /&gt;&lt;br /&gt;As a working example, due to these reasons, &lt;a href="http://code.google.com/p/sharp-architecture/"&gt;S#arp Architecture&lt;/a&gt; projects have a core domain layer which physically &lt;strong&gt;cannot&lt;/strong&gt; have concrete dependencies on the project&amp;#39;s data access layer.&amp;nbsp; Likewise, the controllers layer doesn&amp;#39;t have a concrete reference to the data layer or to NHibernate.&amp;nbsp; In addition to separating concerns, this physical layout of the layers, and the direction of dependencies, acts as a form of implicit documentation to the developers how the layers should be used.&amp;nbsp; E.g., YourProject.Controllers knows nothing about the implementation details found within YourProject.Data; YourProject.Core has no concrete clue what the persistence mechanism is; and YourProject.Controllers could care less about which IoC mechanism you&amp;#39;re using or what static properties Global.asax.cs might be tracking.&lt;br /&gt;&lt;br /&gt;Contrastly (is that a word?), moving the controllers layer into the physical web assembly automatically gives it automatic access to all the references that a web project typically has; references such as your IoC implementation, NHibernate and YourProject.Data.&amp;nbsp; Likewise, mashing any other layers together makes it that much easier for a developer to bleed concerns from one layer into another, inadvertently as it may be.&amp;nbsp; Certainly, there&amp;#39;s a lot to be said for discipline, team agreement, and tools such as NDepend to make sure your team is following the rules, but I feel it&amp;#39;s beneficial to go a bit further to make it that much more difficult to make a mess of things.&amp;nbsp; When considering the wide breadth of skill levels of developers who may ever be touching a project that you&amp;#39;re leading, I&amp;#39;d lean towards enforcing a separation of concerns by default, and make it that much harder for developers to void the warranty. ;)&lt;/p&gt;
&lt;p&gt;If you&amp;#39;d like to rebut, it&amp;#39;s one pound for a five minute argument, but only eight pounds for a course of ten.&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=43683" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Architecture/default.aspx">S#arp Architecture</category></item><item><title>Refactoring Service Dependencies to Separated Interface</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2008/10/30/refactoring-service-dependencies-to-separated-interface.aspx</link><pubDate>Fri, 31 Oct 2008 00:06:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:42831</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>18</slash:comments><description>&lt;p&gt;&lt;span style="font-size:x-small;"&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There are two factors which have a tremendous impact on a team&amp;#39;s likelihood to abandon unit testing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fragile tests which break often and require regular maintenance; and&lt;/li&gt;
&lt;li&gt;Slow tests which add excruciating seconds, if not minutes, to the total time of unit test runs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I find that fragile tests are often those that depend on data within a database, which can become out of synch with the assertions in the unit test, and those that depend on external services.&amp;nbsp; I use the term &amp;quot;services&amp;quot; loosely to define anything that represents an external resource; examples include web services (including RESTful services), file repositories, databases, and remote procedure calls.&amp;nbsp; But these dependencies on services aren&amp;#39;t just bad for keeping unit tests running fast and stable; they can often lead to maintenance problems due to tight coupling.&amp;nbsp; This post presents a common scenario wherein business logic is tightly coupled to a service and provides instruction for refactoring the concrete dependency to a more testable and loosely coupled configuration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separated Interface &amp;amp; Motivations for its Inclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The design pattern known as &amp;quot;Separated Interface&amp;quot; (coined by Martin Fowler; aka &amp;quot;Dependency Inversion&amp;quot; by Robert Martin) is a technique for reducing coupling to concrete dependencies; it achieves this by coding to the interface of the dependency while maintaining the implementation details of the dependency within a separate application layer.&amp;nbsp; You&amp;#39;ll find that the trick of using separated interface, as with any design pattern, is knowing &lt;em&gt;when&lt;/em&gt; to use it appropriately, rather than &lt;em&gt;how&lt;/em&gt; to use it, as the underlying mechanism is rather straight forward.&amp;nbsp; I find it best to use on most external services, as defined earlier, but should still be considered on a case by case basis.&amp;nbsp; You should ask yourself if introducing Separated Interface will make the overall application more maintainable and testable while keeping complexity to a minimum.&amp;nbsp; When used appropriately, the benefits of this decoupling include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improving the ability to unit test &amp;quot;around&amp;quot; the dependency using mocks/stubs,&lt;/li&gt;
&lt;li&gt;Greatly increasing the performance of domain oriented unit tests as a side effect of using mocks/stubs,&lt;/li&gt;
&lt;li&gt;Consolidating dependency communication details to a separate tier,&lt;/li&gt;
&lt;li&gt;Providing a plug-in architecture for external dependencies to be easily swapped without recompiling (e.g., when that 3rd party tool gets upgraded), and&lt;/li&gt;
&lt;li&gt;Allowing developers to develop and compile the domain logic without having all the dependencies in place (e.g., not having to install 3rd party tools A, B, and C just to develop and compile unrelated code).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To illustrate, the following diagram shows two separate assemblies within the project solution.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Project.Core assembly contains all of the domain logic for the application.&amp;nbsp; In addition to domain objects, such as Customer and Order, this example assembly also contains an interface to an external service; in this case, IOrderDao, which represents an interface to a data-access object.&amp;nbsp; Note that this is only the &lt;em&gt;interface&lt;/em&gt; of that service; the domain logic has no idea (or dependency) on the underlying implementation details outside of its conformance to the interface.&lt;/li&gt;
&lt;li&gt;The Project.Data assembly contains all of the implementation details for the interface and contains an assembly reference back to Project.Core.&amp;nbsp; &lt;em&gt;This is the fundamental key to Separated Interface.&lt;/em&gt;&amp;nbsp; In most applications, the data communications and external dependencies are depended on by the business logic.&amp;nbsp; With Separated Interface, the reverse is true wherein the service implementation depends on the interfaces within the domain layer - the true core of the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img width="232" src="http://www.codeproject.com/KB/architecture/NHibernateBestPractices/SeparatedInterface.jpg" alt="Separated Interface" height="216" style="width:232px;height:216px;" title="Separated Interface" /&gt;&lt;/p&gt;
&lt;p&gt;This pattern typically presents two challenges.&amp;nbsp; The first is, how does the domain logic get passed a reference to the actual concrete dependency if all it knows about is an interface?&amp;nbsp; The dependency can get passed to the domain object via its constructor or a setter either manually or with an IoC container, such as &lt;a href="http://www.castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt; or &lt;a href="http://ninject.org/"&gt;Ninject&lt;/a&gt;.&amp;nbsp; (See &lt;a href="http://www.codeproject.com/KB/architecture/DependencyInjection.aspx"&gt;http://www.codeproject.com/KB/architecture/DependencyInjection.aspx&lt;/a&gt; for an example of doing so.)&amp;nbsp; The second and more challenging problem is, how can we get the external resource to depend on our domain layer interface when it&amp;#39;s a third party tool?&amp;nbsp; Recall that we want the service to depend on the domain, not the other way around.&amp;nbsp; In these cases, it&amp;#39;s appropriate to create a &lt;a href="http://en.wikipedia.org/wiki/Facade_pattern"&gt;facade&lt;/a&gt; which wraps the complicated details of communicating with the dependency; then, we simply add an interface for the facade to our domain layer.&amp;nbsp; The following example will walk through looking at a real world smell of a concrete dependency on a third party API - exposed as a RESTful service - and making appropriate modifications to introduce Separated Interface.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Real World Example (aka &amp;quot;the smell&amp;quot;)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To set the appropriate context, assume that (smelly) code has been developed to fulfill the following user story:&amp;nbsp; On a nightly basis, the application will download any new Observations added during the previous day,&amp;nbsp;input into ExternalApp, so that they may be copied locally.&amp;nbsp; (An &amp;quot;observation&amp;quot; is the domain name of the record we&amp;#39;re retrieving.)&amp;nbsp; The idea is that an external application exists, aptly called ExternalApp, which exposes a RESTful service to retrieve newly added records.&amp;nbsp; Our nightly process ties into the service, retrieves the appropriate records, parses the response, and copies the appropriate information locally.&lt;/p&gt;
&lt;p&gt;Our application currently has three tiers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The MySynch.Tests assembly contains unit tests to verify these processes.&amp;nbsp; (No, of course we didn&amp;#39;t call it &amp;quot;MySynch,&amp;quot; but that&amp;#39;ll work for now.)&lt;/li&gt;
&lt;li&gt;The MySynch.Core assembly contains all of the business logic for communicating with the RESTful service and processing the results.&amp;nbsp; Assume it contains one object called ObservationMigrator which encapsulates this logic.&lt;/li&gt;
&lt;li&gt;The MySynch.Console application which is the nightly process, which we won&amp;#39;t concern ourselves with here.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following unit tests, found in the folder MySynch.Tests/Core, verify that the records can be retrieved and that the data migration is successful:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;[TestFixture]
public class ObservationMigratorTests
{
    [Test]
    public void CanRetrieveObservationRecords() {
        ObservationMigrator migrator = new ObservationMigrator();
        IList&amp;lt;Observation&amp;gt; observations = migrator.GetNewObservations();
        Assert.That(observations.Count, Is.GreaterThan(0));
    }
    [Test]
    public void CanMigrateObservationRecords() {
        ObservationMigrator migrator = new ObservationMigrator();
        Result result = migrator.MigrateRecords();
        Assert.That(result.CompletedSuccefully);
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The first test is really verifying if the communications with the RESTful service - the third party tool - are successful.&amp;nbsp; The second test is verifying if the data migration occurs successfully, assuming the communications with the RESTful service are successful.&amp;nbsp; Without even looking at the underlying code, these tests are already unveiling a number of smells:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;It&amp;#39;s obvious that the ObservationMigrator isn&amp;#39;t adhering to the &lt;a href="http://www.objectmentor.com/resources/articles/srp.pdf"&gt;Single Responsibility Principle (SRP)&lt;/a&gt;.&amp;nbsp; It&amp;#39;s providing means to communicate with the service, via GetNewObservations, and it&amp;#39;s responsible for migrating those records to whatever destination.&amp;nbsp; Consequently, it&amp;#39;s likely that it&amp;#39;s inherently complex and that it&amp;#39;s likely to be touched often during maintenance for different reasons.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;The second test is really just trying to make sure that the migration occurs successfully without necessarily wanting to retest proper communications to the RESTful service; that was what the first test was doing.&amp;nbsp; The problem with this is that if the service goes down, in addition to breaking the first test, it&amp;#39;ll start breaking the second test which is really domain-oriented in nature.&amp;nbsp; It would be great if we could test the migration process without having to retest the communications to the service.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Finally, communicating with any external resource via unit tests, especially web-based services, adds seconds to running the unit tests.&amp;nbsp; This can add minutes with hundreds of unit tests.&amp;nbsp; Again, if all we really want to test in the second test is the domain logic for completing the migration, then we shouldn&amp;#39;t be reconfirming communications are working and adding wasted time to running the tests.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Indeed, if we look under the covers at the ObservationMigrator class, we confirm our concerns with respect to SRP and HTTP requests embedded into the business logic:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class ObservationMigrator
{
    public IList&amp;lt;Observation&amp;gt; GetNewObservations() {
        WebClient webClient = new WebClient();
        byte[] response = webClient
            .DownloadData(&amp;quot;http://www.example.com/RESTfulServiceToRetrieveRecords&amp;quot;);
        string responseContent = Encoding.ASCII.GetString(response);
        IList&amp;lt;Observation&amp;gt; observations = new List&amp;lt;Observation&amp;gt;();
        // Lots of complicated parsing...like, crazy complicated
        return observations;
    }
    // Result is a DTO which let&amp;#39;s the caller know if everything succeeded
    public Result MigrateRecords() {
        IList&amp;lt;Observation&amp;gt; observations = GetNewObservations();
        foreach (Observation observation in observations) {
            // Migrate each observation to the appropriate repository
        }
        return new Result(...);
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Refactoring Mechanics&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In refactoring this code, we&amp;#39;ll want to follow the steps below to reduce the amount of work done between tests and to minimize the amount of breaking code in the system at any given point in time.&amp;nbsp; Our goal is to always be very close to a check-in...the &amp;quot;don&amp;#39;t anybody check anything out for the next two days&amp;quot; won&amp;#39;t fly here.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div&gt;Refactor with&amp;nbsp;&lt;a href="http://www.refactoring.com/catalog/extractClass.html"&gt;Extract Class&lt;/a&gt; to pull the RESTful communication and parsing logic into it&amp;#39;s own class.&amp;nbsp; This extracted class becomes the facade to the underlying RESTful API.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Refactor with&amp;nbsp;&lt;a href="http://www.refactoring.com/catalog/extractInterface.html"&gt;Extract Interface&lt;/a&gt; to create an interface for the new API facade.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Refactor with&amp;nbsp;&lt;a href="http://xunitpatterns.com/Dependency%20Injection.html"&gt;Introduce Constructor Injection&lt;/a&gt; to replace the creation of the dependency with a constructor parameter.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Refactor with&amp;nbsp;&lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;Introduce Stub Object&lt;/a&gt; to modify the testing of the migration test to focus on the domain logic rather than on retesting communications with the API.&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;a href="http://www.refactoring.com/catalog/refactorArchitectureByTiers.html"&gt;Refactor Architecture by Tiers&lt;/a&gt; to move the implementation details to a separate tier.&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Step 1:&amp;nbsp; Extract Class&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So without further ado, let&amp;#39;s start with step 1, extracting a class to act as a facade to the underlying RESTful API.&amp;nbsp; As always, we begin with a test; let&amp;#39;s do so by adding a new test as follows:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;[TestFixture]
[Category(&amp;quot;ExternalApp Integration&amp;quot;)]
public class ObservationRetrieverTests
{
    [Test]
    public void CanRetrieveRecordsToImport() {
        ObservationRetriever observationRetriever = new ObservationRetriever();
        IList&amp;lt;Observation&amp;gt; observations = observationRetriever.GetNewObservations();
        Assert.That(observations.Count, Is.GreaterThan(0));
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Note that we&amp;#39;ve added this fixture to a category called &amp;quot;ExternalApp Integration.&amp;quot;&amp;nbsp; Doing so, we&amp;#39;re able to conveniently turn off this slow-running category of unit tests while we&amp;#39;re working on other areas of the application.&amp;nbsp; Compiling this breaks, so the next step is to add just enough code to MySynch.Core to get the test to compile:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:x-small;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class ObservationRetriever
{
    public IList&amp;lt;Observation&amp;gt; GetNewObservations() {
        throw new NotImplementedException();
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You should now be able to run the test and see it fail with a NotImplementedException.&amp;nbsp; Yes, you want it to fail...a failing test is your next goal to fix.&amp;nbsp; So now let&amp;#39;s write enough code to get it to pass by copying the GetNewObservations() method from ObservationMigrator into ObservationRetriever:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class ObservationRetriever
{
    public IList&amp;lt;Observation&amp;gt; GetNewObservations() {
        WebClient webClient = new WebClient();
        byte[] response = webClient
            .DownloadData(&amp;quot;http://www.example.com/RESTfulServiceToRetrieveRecords&amp;quot;);
        string responseContent = Encoding.ASCII.GetString(response);
        IList&amp;lt;Observation&amp;gt; observations = new List&amp;lt;Observation&amp;gt;();
        // Lots of complicated parsing...like, crazy complicated
        return observations;
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;All the unit tests should now be passing again.&amp;nbsp; But we&amp;#39;ve introduced a problem...the smell of duplicated code.&amp;nbsp; We can remove this smell by replacing the ObservationMigrator.GetNewObservations() method with the creation of an ObservationRetriever object and the invocation of the method therein:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class ObservationMigrator
{
    public Result MigrateRecords() {
        ObservationRetriever observationRetriever = new ObservationRetriever();
        IList&amp;lt;Observation&amp;gt; observations = observationRetriever.GetNewObservations();
        foreach (Observation observation in observations) {
            // Migrate each observation to the appropriate repository
        }
        return new Result(...);
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You&amp;#39;ll need to drop ObservationMigratorTests.CanRetrieveObservationRecords() to get it to compile; but all the tests should still be passing.&amp;nbsp; We&amp;#39;ve officially completed step 1 by extracting a class from the ObservationMigrator class into a facade class which only concerns itself with communicating with the RESTful API and parsing the results.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2:&amp;nbsp; Extract Interface&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Step 2 is introducing the interface to our service.&amp;nbsp; Instead of creating a new test, we simply modify the ObservationRetrieverTests.CanRetrieveRecordsToImport() method to invoke GetNewObservations() via an interface rather than the concrete object itself:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;[TestFixture]
[Category(&amp;quot;ExternalApp Integration&amp;quot;)]
public class ObservationRetrieverTests
{
    [Test]
    public void CanRetrieveRecordsToImport() {
        // Note the &amp;quot;I&amp;quot; that&amp;#39;s been introduced below
        IObservationRetriever observationRetriever = new ObservationRetriever();
        IList&amp;lt;Observation&amp;gt; observations = observationRetriever.GetNewObservations();
        Assert.That(observations.Count, Is.GreaterThan(0));
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Since a quick compilation shows that this isn&amp;#39;t compilable (and it shouldn&amp;#39;t be), let&amp;#39;s add an interface to MySynch.Core which reflects the method on our facade class, and have ObservationRetriever then implement that interface.&amp;nbsp; First, the interface that we need to add to MySynch.Core:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public interface IObservationRetriever
{
    IList&amp;lt;Observation&amp;gt; GetNewObservations();
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Then, simply have the ObservationRetriever class implement this interface:&amp;nbsp; public class ObservationRetriever : IObservationRetriever { ...&lt;/p&gt;
&lt;p&gt;All unit tests should be passing again...oh, happy days again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3:&amp;nbsp; Introduce Constructor Injection&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The ObservationMigrator class still has a concrete dependency on the ObservationRetriever...damn that concrete dependency!!&amp;nbsp; So let&amp;#39;s now introduce constructor injection to remove this tight coupling.&amp;nbsp; Guess where we&amp;#39;re going to start...that&amp;#39;s right, back in a unit test.&amp;nbsp; But here again, we don&amp;#39;t need to add a new test, we simply need to alter an existing one, ObservationMigratorTests.CanMigrateObservationRecords().&amp;nbsp; The modified test should be as follows:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;[Test]
public void CanMigrateObservationRecords() {
    IObservationRetriever observationRetriever = new ObservationRetriever();
    ObservationMigrator migrator = new ObservationMigrator(observationRetriever);
    Result result = migrator.MigrateRecords();
    Assert.That(result.CompletedSuccefully);
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;All we&amp;#39;re intending to do here is to pass an instance of IObservationRetriever to the migration utility rather than having it create its own.&amp;nbsp; Tying to compile breaks the build, so now let&amp;#39;s write just enough code to get this puppy to compile...usually we&amp;#39;d write just enough to compile and then just enough to pass, but I&amp;#39;m getting tired of writing, so we&amp;#39;ll combine the two here:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;public class ObservationMigrator
{
    public ObservationMigrator(IObservationRetriever observationRetriever) {
        // Let&amp;#39;s do a design-by-contract (DbC) check to make sure we&amp;#39;re not 
        // given a null service dependency. For more about this, see 
        // http://devlicio.us/blogs/billy_mccafferty/archive/2006/09/22/Design_2D00_by_2D00_Contract_3A00_-A-Practical-Introduction.aspx
        Check.Require(observationRetriever != null, 
            &amp;quot;observationRetriever may not be null&amp;quot;);
        this.observationRetriever = observationRetriever;
    }
    public Result MigrateRecords() {
        IList&amp;lt;Observation&amp;gt; observations = observationRetriever.GetNewObservations();
        foreach (Observation observation in observations) {
            // Migrate each observation to the appropriate repository
        }
        return new Result(...);
    }
    private IObservationRetriever observationRetriever;
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;With these changes, everything should now compile and the tests should be passing again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4:&amp;nbsp; Introduce Stub Object&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As mentioned in the previous gripes against the original code, the ObservationMigratorTests.CanMigrateObservationRecords() test shouldn&amp;#39;t be worried about communicating with the RESTful service; it should only be concerned with ensuring the migration occurs assuming the RESTful service is working as expected.&amp;nbsp; The ObservationRetrieverTests.CanRetrieveRecordsToImport() test is already verifying that the service is working, so it&amp;#39;s just adding extra time and complexity to the ObservationMigratorTests.CanMigrateObservationRecords() test.&amp;nbsp; Therefore, let&amp;#39;s now introduce a stub object to simulate communications with the RESTful service.&amp;nbsp; Keep in mind that this modification isn&amp;#39;t being done to test new functionality; instead, it&amp;#39;s a refactoring to an existing unit test to properly focus the test&amp;#39;s attention on the domain logic.&amp;nbsp; Accordingly, the ObservationMigratorTests now reflects the following:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;[TestFixture]
public class ObservationMigratorTests
{
    [Test]
    public void CanMigrateObservationRecords() {
        IObservationRetriever observationRetriever = new ObservationRetrieverStub();
        ObservationMigrator migrator = new ObservationMigrator(observationRetriever);
        Result result = migrator.MigrateRecords();
        Assert.That(result.CompletedSuccefully);
    }
    private class ObservationRetrieverStub : IObservationRetriever
    {
        public IList&amp;lt;Observation&amp;gt; GetNewObservations() {
            IList&amp;lt;Observation&amp;gt; observations = new List&amp;lt;Observation&amp;gt;();
            observations.Add(new Observation(...));
            observations.Add(new Observation(...));
            observations.Add(new Observation(...));
            return observations;
        }
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the unit test above, a stub object has been created which implements IObservationRetriever and fakes communications with the external service to retrieve three new Observation records.&amp;nbsp; The ObservationMigrator.MigrateRecords() method happily uses this stub, not knowing that it&amp;#39;s actually not talking to the external RESTful service.&amp;nbsp; We&amp;#39;re now focusing this unit test on testing the domain logic, outside of communicating with the RESTful service.&amp;nbsp; Again, the ObservationRetrieverTests fixture of tests is already testing the communications with this service and related parsing functionality...no need to retest it here.&lt;/p&gt;
&lt;p&gt;In such a simple case, where the interface only has one method to implement, a stub is perfectly adequate.&amp;nbsp; But we&amp;#39;re passing three observations to the migration step without verifying that all three were processed...we might as well have just passed one, or none at all for that matter.&amp;nbsp; This test could be&amp;nbsp;extended in two ways to verify the underlying migration processed each and every Observation appropriately.&amp;nbsp; The first is that we could include the status of how many observations were migrated within the Result object returned from the migration step.&amp;nbsp; The&amp;nbsp;other way is to use a mock object, instead of a stub, which can verify that the expected behavior is occurring under the scenes.&amp;nbsp; Although mocking is beyond the scope of this post, I encourage you to take a look at &lt;a href="http://xunitpatterns.com/"&gt;http://xunitpatterns.com/&lt;/a&gt;&amp;nbsp;and &lt;a href="http://ayende.com/wiki/Rhino+Mocks+Documentation.ashx"&gt;Rhino Mocks&lt;/a&gt; for more information.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 5:&amp;nbsp; Refactor Architecture by Tiers&lt;/strong&gt;&lt;br /&gt;(i.e., add the &amp;quot;Separated&amp;quot; part of &amp;quot;Separated Interface&amp;quot;)&lt;/p&gt;
&lt;p&gt;After all of this, we&amp;#39;re finally at the point of culmination:&amp;nbsp; the introduction of the Separated Interface.&amp;nbsp; But by now, it&amp;#39;s rather anticlimactic as the hard work has already been done.&amp;nbsp; Nonetheless...on with the anticlimactic conclusion!&amp;nbsp; A problem with the solution as it stands is that the service facade still physically resides in the MySynch.Core assembly.&amp;nbsp; Consequently, there&amp;#39;s nothing we can do to prevent developers from bypassing our elegant interface and go straight to the ObservationRetriever class itself.&amp;nbsp; This is a wonderful side benefit of introducing Separated Interface; it forces developers to adhere to certain design decisions.&amp;nbsp; To mitigate this concern, and to remove all coupling from MySynch.Core to the implementation details of ObservationRetriever, we&amp;#39;ll refactor the architecture itself to move the implementation details to a separate tier.&amp;nbsp; Let&amp;#39;s head back to the tests assembly and add a new &lt;em&gt;folder&lt;/em&gt; called ExternalAppIntegrator; recall that &amp;quot;ExternalApp&amp;quot; is the name of our 3rd party tool which exposes the RESTful service.&amp;nbsp; Now move the ObservationRetrieverTests class to this new folder.&amp;nbsp; This new folder represents the new class library that we&amp;#39;ll be introducing.&amp;nbsp; The ObservationRetrieverTests class should then be modified to reflect the change in namespace and a using statement to pull in the class library which we have not yet created (remember...write the test and &lt;em&gt;then&lt;/em&gt; write the code to get the test to pass):&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre name="code" class="c#:nogutter:nocontrols"&gt;using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using System.Collections.Generic;
// The compiler will throw an error on the following line since 
// the ExternalAppIntegrator.Core class library doesn&amp;#39;t exist yet
using ExternalAppIntegrator.Core;
namespace Tests.ExternalAppIntegrator.Core
{
    [TestFixture]
    [Category(&amp;quot;ExternalApp Integration&amp;quot;)]
    public class ObservationRetrieverTests
    {
        [Test]
        public void CanRetrieveRecordsToImport() {
            IObservationRetriever observationRetriever = 
                new ObservationRetriever();
            IList&amp;lt;Observation&amp;gt; observations = 
                observationRetriever.GetNewObservations();
            Assert.That(observations.Count, Is.GreaterThan(0));
        }
    }
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We&amp;#39;ve introduced some work for us here, but we will overcome!&amp;nbsp; Firstly, create a new class library called &amp;quot;ExternalAppIntegrator.Core&amp;quot; and add a reference to it from our MySynch.Tests assembly.&amp;nbsp; Next, move the class MySynch.Core/ObservationRetriever.cs to the ExternalAppIntegrator.Core class library...be sure you move it completely by deleting the original.&amp;nbsp; Ack...a new problem now!&amp;nbsp; We&amp;#39;ve moved the class but it depended upon IObservationRetriever.&amp;nbsp; Fear not!&amp;nbsp; Simply add a reference to MySynch.Core to the ExternalAppIntegrator.Core class library.&amp;nbsp; Since we&amp;#39;ve removed all other dependencies to the ObservationRetriever from MySynch.Core, all the unit tests will still pass.&amp;nbsp; As a matter of fact, we&amp;#39;re done!&lt;/p&gt;
&lt;p&gt;But wait, how do we know it&amp;#39;s working?&amp;nbsp; Although not necessary, since the unit testing has proven&amp;nbsp;that all of the&amp;nbsp;inner workings are in order, we can make sure our Separated Interface is working as expected with the rest of the migration process by going back to ObservationMigratorTests.CanMigrateObservationRecords() and replacing the creation of the stub object with our concrete implementation:&amp;nbsp; IObservationRetriever observationRetriever = new ObservationRetriever();&amp;nbsp; With that said, I&amp;#39;d quickly change it back to using the stub so that we can keep that unit test focused on the domain rather than communications with the RESTful service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We&amp;#39;ve taken some rather smelly dependencies and moved them to a dedicated class library which concerns itself with the management of a facade over the external API.&amp;nbsp; We finished by having this facade implement an interface found without our domain layer so that the domain layers could communicate to the external API without having a direct, concrete dependency on the implmentation details.&amp;nbsp; The hope is that this has made our code more testable, less coupled, and more maintainable down the road.&amp;nbsp; The cost has been the introduction of increased complexity.&amp;nbsp; Accordingly, care should be taken before the introduction of any design pattern to ensure that the pattern itself is &amp;quot;pulling its weight,&amp;quot; so to speak.&lt;/p&gt;
&lt;p&gt;I have found immense value from this design pattern; it has been particularly handy for removing direct dependencies on data access objects.&amp;nbsp; The sample code that comes along with&amp;nbsp;&lt;a href="http://code.google.com/p/sharp-architecture/"&gt;S#arp Architecture&lt;/a&gt; has a full example of just such an instance.&amp;nbsp; Happy coding!&lt;/p&gt;
&lt;p&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=42831" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Architecture/default.aspx">S#arp Architecture</category></item><item><title>S#arp Architecture: a new home, upgrades and a logo!</title><link>http://devlicio.us/blogs/billy_mccafferty/archive/2008/08/08/s-arp-architecture-a-new-home-upgrades-and-a-logo.aspx</link><pubDate>Fri, 08 Aug 2008 20:19:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:41767</guid><dc:creator>Billy McCafferty</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;&lt;img width="206" vspace="6" hspace="6" height="91" align="right" alt="S#arp Architecture" style="width:206px;height:91px;" title="S#arp Architecture" src="http://devlicio.us/blogs/billy_mccafferty/sharp_arch.jpg" /&gt;To facilitate better integration with SVN clients, S#arp Architecture has been moved to Google Code at &lt;a href="http://code.google.com/p/sharp-architecture"&gt;http://code.google.com/p/sharp-architecture&lt;/a&gt;.&amp;nbsp; Additionally,&amp;nbsp;a discussion group has just been setup on Google Groups at &lt;a href="http://groups.google.com/group/sharp-architecture"&gt;http://groups.google.com/group/sharp-architecture&lt;/a&gt;&amp;nbsp;to support use of the architecture, discuss the ideas and patterns behind it, offer suggestions for improvement, and exchange ideas for using it in real-world applications.&lt;/p&gt;
&lt;p&gt;So why a bonsai tree on the logo?&amp;nbsp; Bonsai trees are small, have years of&amp;nbsp;practice&amp;nbsp;trained into their shape, and have a solid&amp;nbsp;core...all the attributes that I hope S#arp Architecture exhibits.&amp;nbsp; Besides, if they&amp;#39;re cool enough for Mr. Miyagi, then the choice is obvious!&lt;/p&gt;
&lt;p&gt;By the way, &lt;a href="http://code.google.com/p/sharp-architecture/downloads/list"&gt;S#arp Architecture 0.7.3&lt;/a&gt; currently supports ASP.NET MVC Preview 4 and NHibernate 2.0 CR 1.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;br /&gt;Billy McCafferty&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=41767" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/Architecture/default.aspx">Architecture</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/MVC.NET/default.aspx">MVC.NET</category><category domain="http://devlicio.us/blogs/billy_mccafferty/archive/tags/S_2300_arp+Architecture/default.aspx">S#arp Architecture</category></item></channel></rss>