<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Elegant Code &#187; Architecture and Design</title>
	<atom:link href="http://elegantcode.com/tag/architecture-and-design/feed/" rel="self" type="application/rss+xml" />
	<link>http://elegantcode.com</link>
	<description></description>
	<lastBuildDate>Sun, 12 Feb 2012 04:40:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Microsoft&#8217;s ALM Story</title>
		<link>http://elegantcode.com/2008/06/12/microsofts-alm-story/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=microsofts-alm-story</link>
		<comments>http://elegantcode.com/2008/06/12/microsofts-alm-story/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 04:31:31 +0000</pubDate>
		<dc:creator>David Starr</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Team System]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/06/12/microsofts-alm-story/</guid>
		<description><![CDATA[Microsoft has embraced the idea of Application Lifecycle Management as a framework upon their software development tools can be positioned. This is a great notion, and one that will take several years of investment even from a company with as many resources as Microsoft. ALM is the enterprise software development holy grail that IBM sought [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft has embraced the idea of <a href="http://en.wikipedia.org/wiki/Application_Lifecycle_Management" target="_blank">Application Lifecycle Management</a> as a framework upon their software development tools can be positioned. This is a great notion, and one that will take several years of investment even from a company with as many resources as Microsoft. </p>
<p>ALM is the enterprise software development holy grail that IBM sought for years and invested in with the <a href="http://www-306.ibm.com/software/rational/" target="_blank">Rational tools</a>. And although there is a tremendous value in prescriptive guidance in enterprise development models, there is a natural tension between the ALM crowd and <em>Development as a Craft</em> advocates. ALM, after all, is all about quantifying, measuring, predicting, planning, and economies of scale. Ironically, the kind of transparency and predictability called for by the minimalist Agile community is the same goal of ALM tooling offered by Big Blue and now by the new blue in Redmond.</p>
<p>How are Microsoft products staged to lay across the ALM model? The story today is mixed.</p>
<table cellspacing="0" cellpadding="2" width="366" border="1">
<tbody>
<tr>
<td valign="top" width="160"><strong>ALM Principle</strong></td>
<td valign="top" width="204"><strong>MS Product Answer</strong></td>
</tr>
<tr>
<td valign="top" width="176">Project Management</td>
<td valign="top" width="213">Portfolio Server, Project Server, MS Project</td>
</tr>
<tr>
<td valign="top" width="181">Project Tacking</td>
<td valign="top" width="214">TFS, MS Project</td>
</tr>
<tr>
<td valign="top" width="184">Requirements Planning</td>
<td valign="top" width="213">3rd Party Solutions</td>
</tr>
<tr>
<td valign="top" width="185">Design and Development</td>
<td valign="top" width="212">Visio, Visual Studio</td>
</tr>
<tr>
<td valign="top" width="186">Quality Assurance</td>
<td valign="top" width="211">Visual Studio</td>
</tr>
<tr>
<td valign="top" width="187">Release Management</td>
<td valign="top" width="211">System Center, Team Build</td>
</tr>
<tr>
<td valign="top" width="187">Helpdesk</td>
<td valign="top" width="211">SharePoint?</td>
</tr>
</tbody>
</table>
<p>Your familiarity with these products may lead you to the same conclusion that many have already reached. The products in the stack currently fail to integrate cleanly and many provide only a starting taste of the functionality needed to realize the ALM vision. The story is obviously a little muddy today. But what&#8217;s next?</p>
<p>Team System Rosario promises much improvement in the areas of tracking, design, quality assurance, and development. Significant bridges are also being started toward improving the release management story.</p>
<p>That won&#8217;t do it all, of course. There are other pieces needed in the stack that will need to be freshened up including operational support tools. Microsoft is in hot pursuit of filling this gap with a host of products under the <a href="http://www.microsoft.com/systemcenter/en/us/products.aspx" target="_blank">System Center umbrella of products</a>. An actual helpdesk management system to displace the TechExcels and Remedys of the world is essential here.</p>
<p>The point is, MS has its sights set on a complete ALM story and are focusing on the midsize market, as Microsoft is so good at doing. </p>
<h2>The Good</h2>
<p>A focus on ALM in the Microsoft stack will have a tremendous impact on software development and delivery as we know it. Interoperable components in the pipeline will help bridge those gaps in midsize organizations that are typically only filled in large enterprises. Transparency will be ubiquitous.</p>
<p>Given the open nature of products being developed at MS these days, I have high hopes that these systems will truly be pluggable, so that if you want to bridge TFS to Remedy (for example) doing so is not rocket surgery. Web services are great, aren&#8217;t they?</p>
<h2>Concerns</h2>
<p>There is a fine line between managing for predictability and &#8216;command and control&#8217;. Tools like those in this stack are like guns. They can be used for good, but misuse is more common than not. </p>
<p>Tooling like this gives every non-tool Agilist out there genuine pause, and with good reason. The history of stewardship in complex models like this is less than stellar. That is to say, this tooling can provide huge value, and the basis for crushing souls. Let&#8217;s be careful how we wield them.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/06/12/microsofts-alm-story/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where to start a new program</title>
		<link>http://elegantcode.com/2008/06/08/where-to-start-a-new-program/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=where-to-start-a-new-program</link>
		<comments>http://elegantcode.com/2008/06/08/where-to-start-a-new-program/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 19:50:39 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[Design Patterns]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/06/08/where-to-start-a-new-program/</guid>
		<description><![CDATA[Here as an interesting question that popped up at my user group meeting last night, when you are starting a new program (green field development), where do you get started?&#160; I find these questions interesting because there really is no correct answer, but a persons answer will tell you something about how they problem solve. [...]]]></description>
			<content:encoded><![CDATA[<p>Here as an interesting question that popped up at my user group meeting last night, when you are starting a new program (green field development), where do you get started?&nbsp; I find these questions interesting because there really is no correct answer, but a persons answer will tell you something about how they problem solve.</p>
<p>Depending on who you ask you will likely get one of two answers.&nbsp; If you are talking with a data guy, he will say to start with the database.&nbsp; If you are dealing with a visual guy, he will say to start with the UI.&nbsp; Historically, I did a conglomeration of those two ideas, creating both the UI and the database at the same time, letting the two drive each other.&nbsp; But I&#8217;m weird, I&#8217;m a visual/data guy.</p>
<p>Lately though, I&#8217;ve started to thing about a third approach.&nbsp; Starting in the middle.&nbsp; No UI, no database, just the data classes.&nbsp; This approach has been spurred on buy a couple of things.&nbsp; Namely, test driven development (TDD), design patterns, and domain driven design.</p>
<p>TDD really is the glue that allows all of this to happen.&nbsp; I can start in the middle because I can run the code in the middle any time I want.&nbsp; I just have to write a test.&nbsp; No having to wade through multiple layers of UI to test out some small chunk ok UI is a great productivity gain for me.</p>
<p>Next is design patterns.&nbsp; This is what gives you a reference for how to approach your code.&nbsp; That said, this isn&#8217;t about making everything absolutely perfect from the get go, but it is nice to know where you are going to made your comprises early on.</p>
<p>But all of that does not explain where I begin.&nbsp; That is where Domain Driven Design (DDD) kicks in.&nbsp; For those not familiar with the concept, you can read up on <a href="http://en.wikipedia.org/wiki/Domain-driven_design">wikipedia</a>, buy <a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1212806974&amp;sr=8-1">The Book</a>, or buy one of the <a href="http://www.amazon.com/s?ie=UTF8&amp;tag=mozilla-20&amp;index=blended&amp;link%5Fcode=qs&amp;field-keywords=domain%20driven%20design&amp;sourceid=Mozilla-search">various other references</a>.&nbsp;&nbsp; One of the concepts in DDD (I&#8217;m still reading the book) is setting up something called a <a href="http://www.domaindrivendesign.org/discussion/messageboardarchive/UbiquitousLanguage.html">ubiquitous language</a>.</p>
<p>The ubiquitous language is actually trying to solve a problem that I have seen happen on many projects I&#8217;ve been apart of (but not always my fault).&nbsp; At some point there is a linguistic difference between the nouns that the customer uses and the nouns that the programmers use.&nbsp; By focusing on the language first, you are attempting to head that off at the pass.</p>
<p>These nouns consist of your domain classes and your tables and columns, they move everywhere&#8230;but not always consistently.&nbsp; Consistency does matter.&nbsp; Inconsistency is what leads to rather confusing conversations with people and everyone scratching their heads about &#8220;what just happened&#8221;.&nbsp; So, this is the middle that I start with.</p>
<p>But before you start&#8230;</p>
<p>One of the other guys in the group was an actual data guy.&nbsp; The systems he has written worked with more data than yours does.&nbsp; Trust me on that.&nbsp; Historically, his biggest consideration was data input speed.&nbsp; I don&#8217;t think I would start in the middle if that was my biggest concern.&nbsp; In that case you do start with the database, you tune for speed.&nbsp; You also don&#8217;t use as many domain classes, and you tend to throw away your ORM solution and just hit the database layer directly via Ado.Net.</p>
<p>But lets face it, that doesn&#8217;t happen very often.&nbsp; Most business applications aren&#8217;t going to touch what the architecture can take.&nbsp; It is amazing how many horribly written applications with very inefficient code run just fine.&nbsp; Most of my speed issues could be solved by indexing tables and changing generic lists to generic dictionaries (more on that later).&nbsp; Architect your applications for how they are going to be used.&nbsp; Most of my web applications have a max usage of 100 simultaneous users.&nbsp; If the data access is slightly slower I&#8217;ll take that hit for programmer efficiency.&nbsp; If you are designing Amazon.com, you code for through-put.</p>
<p>OK, someone is going to disagree with this&#8230;I can already feel it.&nbsp; Please take a moment to register your displeasure in the comments.&nbsp; I would love to hear it.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/06/08/where-to-start-a-new-program/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Architecture Modeling in Rosario with Peter Provost</title>
		<link>http://elegantcode.com/2008/06/06/architecture-modeling-in-rosario-with-peter-provost/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=architecture-modeling-in-rosario-with-peter-provost</link>
		<comments>http://elegantcode.com/2008/06/06/architecture-modeling-in-rosario-with-peter-provost/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 15:33:16 +0000</pubDate>
		<dc:creator>David Starr</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[Team System]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/06/06/architecture-modeling-in-rosario-with-peter-provost/</guid>
		<description><![CDATA[Yes, that Peter Provost, and this is a great Tech Ed session. We know that the modeling tools in Team System 2008 are, well&#8230; there&#8217;s room for improvement. How valuable is a Logical Data Center Design Model when we can&#8217;t derive it from a reverse engineering action? There has also been much frustration with the [...]]]></description>
			<content:encoded><![CDATA[<p>Yes, that Peter Provost, and this is a great Tech Ed session. </p>
<p>We know that the modeling tools in Team System 2008 are, well&#8230; there&#8217;s room for improvement. How valuable is a Logical Data Center Design Model when we can&#8217;t derive it from a reverse engineering action? There has also been much frustration with the lack of standard UML support in Visual Studio. Guess what?</p>
<p>Rosario proposes that we promote modeling to a first class citizen of the complete Application Lifecycle Management model. Here&#8217;s my major takeaway: The way modeling is being supported enables visual exploration of your code base in a way that is seamless with the development process. This can honestly change the fundamental code development experience.</p>
<p>Also, I can plan on sun setting all my organizations Sparx licenses. Cool.</p>
<ul>
<li>UML 2.1 at the logical layer</li>
<li>DSLs at the physical layer</li>
<li>Generate models from existing assets. This is being discussed as &#8220;Architectural Discovery&#8221; which is a hilarious term in itself.</li>
<li>The April CTP has the following </li>
<ul>
<li>UML Class Diagram</li>
<li>UML Use Cases Diagram</li>
<li>UML Sequence Diagram</li>
<li>UML Component Diagram</li>
<li>UML Activity Diagram</li>
<li>Architecture Explorer</li>
<li>There is a unifying model underlying all of this, the diagrams are simply views upon that model.</li>
</ul>
<li>Newer versions will have some of the features we got to see today. These will come in another CTP later this year.</li>
<ul>
<li>Layer Diagram</li>
<ul>
<li>Seriously cool, this allows to separate concerns of our tiers in a system.</li>
<li>I can bind my namespaces to logical layers of my application</li>
</ul>
<li>Also has some seriously cool visualization tools for looking through your code. </li>
<ul>
<li>Using these views, we can see our cohesion and inheritance in physical form. </li>
<li>How about namespace visualization using a graph model? Dang, this is cool.</li>
<li>How about a dependency visualization? NDepend better look out because this one isn&#8217;t half bad.</li>
<li>AND, all views enable us to click right through to our source code. Neato.</li>
</ul>
<li>XMI support (seriously, wow). This means we can export models from other applications like Sparx EA, Altova, and Rational and bring them right into Visual Studio. Oh, and it will pull Visio models as well.</li>
<li>Round tripping of component models to code</li>
</ul>
<li>Peter actually built some sequence diagrams and I gotta say that this UX is going to be MUCH better than Enterprise Architect, which will soon loose it&#8217;s Market Share. Even use cases look neater.</li>
<li>Sequence diagrams can be round tripped with classes and even methods. This means we can examine the complexity of our code at a usable level, and do it visually. </li>
</ul>
<p>What if you could prescribe separation of tiers and limit leaky abstractions?</p>
<h2>Nuggets</h2>
<p>&#8220;Any system should be possible to represent on a white broad in no more than 13 boxes.&#8221;</p>
<p>&#8220;Using model is simply a way of managing complexity.&#8221;</p>
<p>&#8220;There will be a model store capability that means we don&#8217;t need to keep our models in the same solutions with our code.&#8221; But you can <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Because the models are all built on DSLs, there is someone out there who has automated the process of building test cases from activity diagrams. That is hotter than a 2 dollar pistol.</p>
<p>We can attach other files like Word files to your model itself. </p>
<p>What if we could could light up the models in the debugger to see highlighting of current activity in a sequence diagram? Neato.</p>
<p>They are trying to figure out how to include support for generating design patterns like found in EA and Rational. This is fun because you can generate domain specific code with a fundamental implementation in a known design pattern like Forward Controller or something.</p>
<p>I need a bigger monitor. Seriously, boss. I need a bigger monitor.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/06/06/architecture-modeling-in-rosario-with-peter-provost/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Art of Assembly Versions</title>
		<link>http://elegantcode.com/2008/06/05/the-art-of-assembly-versions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-art-of-assembly-versions</link>
		<comments>http://elegantcode.com/2008/06/05/the-art-of-assembly-versions/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 16:45:11 +0000</pubDate>
		<dc:creator>Tony Rasa</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/06/05/the-art-of-assembly-versions/</guid>
		<description><![CDATA[One of the things I do is writing and maintaining shared components that are used by other developers, for all sorts of projects.&#160; One problem that can really hurt is not managing your version numbers vigilantly.&#160; For example, say you&#8217;ve got two separate projects using CleverTool.dll, version 1.0.0.0 &#8211; are you confident that they both [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I do is writing and maintaining shared components that are used by other developers, for all sorts of projects.&nbsp; One problem that can really hurt is not managing your version numbers vigilantly.&nbsp; For example, say you&#8217;ve got two separate projects using CleverTool.dll, version 1.0.0.0 &#8211; are you confident that they both reference the same bits?&nbsp; Some truly great bugs happen when they&#8217;re different &#8211; if one has an important bugfix, and the other has different namespaces, and you&#8217;re wondering why this &#8220;works on my machine&#8230;&#8221;&nbsp; Even better if they&#8217;re signed and you&#8217;re using the GAC to help keep track&#8230; Lots of fun.</p>
<p>So this is, in brief, the pattern that I use to communicate changes via version numbers.&nbsp; It&#8217;s one way to handle the problem, but of course not the only way.&nbsp; Also, this is for the projects that aren&#8217;t [yet] under automated build like CruiseControl; for those I use a different pattern, which will be a separate post..</p>
<h4>Building Versions</h4>
<p>The .NET assembly version is broken down into {<em>Major</em>}.{<em>Minor</em>}.{<em>Revision</em>}.{<em>Build</em>} (although there is some disagreement about this, and some inconsistent documentation&#8230; but lets ignore that for now.&nbsp; You like your definition better?&nbsp; Great, use that one instead.)&nbsp; </p>
<p><strong>Major:</strong> Obviously, big sweeping changes to the project: changing .NET framework versions, changing major supporting libraries, or for that matter just rewriting the thing.&nbsp; There is absolutely no expectation of interface compatibility between major versions, and those upgrading should expect breaking changes and have to do some work on their part to take advantage of the new version.</p>
<p><strong>Minor:</strong> Slightly less sweeping changes, but still pretty big: major architectural activity, inclusion of big feature sets, etc.&nbsp; There is no expectation of interface compatibility and there will likely be breaking changes.&nbsp; Upgrading minor versions should expect some changes.&nbsp; </p>
<p>There is a lot of room for interpretation between what&#8217;s Major and Minor, personally I try to reserve Major for the biggest of changes, and do minor revisions more often.&nbsp; But this is left up to your discretion.</p>
<p><strong>Revision:</strong> A change to a project that alters its public interface, but doesn&#8217;t necessarily represent adding big features.&nbsp; This could be adding smaller functionality or more commonly, bugfixes and refactoring.&nbsp; Revisions <em>might </em>maintain interface compatibility.&nbsp; Upgrading revisions should be straightforward.</p>
<p><strong>Build: </strong>A change that doesn&#8217;t alter the public interface, or is otherwise &#8220;very small.&#8221;&nbsp; We need to re-release the project, and don&#8217;t want someone to confuse this release with the previous one.&nbsp; Builds should keep interface compatibility.&nbsp; Upgrading the build shouldn&#8217;t require changes to the user&#8217;s code.&nbsp; Often CruiseControl.NET gets put in charge of this number, but that&#8217;s a topic for another day.</p>
<p>None of this is absolute &#8211; there is a ton of space between each of these categories, and this sort of thing is usually left up to the developer&#8217;s own discretion.&nbsp; I think it&#8217;s important for your organization, or at least for a developer, to have a method to your version naming madness.&nbsp; You like your method better?&nbsp; Great!&nbsp; Post it in the comments for all of us to learn from.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/06/05/the-art-of-assembly-versions/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Get Started Writing Testable Code</title>
		<link>http://elegantcode.com/2008/05/20/get-started-writing-testable-code/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-started-writing-testable-code</link>
		<comments>http://elegantcode.com/2008/05/20/get-started-writing-testable-code/#comments</comments>
		<pubDate>Tue, 20 May 2008 16:11:11 +0000</pubDate>
		<dc:creator>Tony Rasa</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/05/20/get-started-writing-testable-code/</guid>
		<description><![CDATA[Testing is hard.&#160; Writing unit tests, regardless of if you write them first or last, is hard.&#160; This is because creating a design that allows you to write testable code is difficult at first &#8211; you have to break some old habits that you&#8217;ve relied on for a long time, and learn some new habits.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Testing is hard.&#160; Writing unit tests, regardless of if you write them first or last, is hard.&#160; This is because creating a design that allows you to write testable code is difficult at first &#8211; you have to break some old habits that you&#8217;ve relied on for a long time, and learn some new habits.&#160; </p>
<p>Many of the technologies we work with don&#8217;t easily lend themselves to unit testing: web pages, stored procedures, 3rd party controls.&#160; You&#8217;ll probably have to learn some new technologies that make testing practical, which also takes time and energy.&#160; You might have to write test barriers between the &quot;untestable&quot; part, and the logic; moving as much logic out of the hard to reach area and into easily tested code as possible.&#160; Which at a minimum represents more classes, more complexity, more typing&#8230;</p>
<p>Writing testable code is hard, and requires a shift in how you write code.&#160; This shift won&#8217;t come overnight.&#160; At first you will write &quot;sort of&quot; testable code, hopefully following some ideas laid out by other codebases (Various parts of <a href="http://www.castleproject.org/">Castle</a>, <a href="http://www.codeplex.com/aspnet">ASP.NET MVC</a>, and Rhino-Commons and other examples by <a href="http://www.ayende.com/Blog/">Oren Eini</a> are some good places to start).&#160; You will end up making mistakes, and a few months later you&#8217;ll look back at this code and wish you had done things differently.&#160; If you&#8217;re not having that experience with your code, then how have you improved as a developer?&#160; If you look at last year&#8217;s code and think that you&#8217;d change absolutely nothing, doesn&#8217;t that at least imply you haven&#8217;t improved your skills?</p>
<p><em>&quot;But, we don&#8217;t have time to write unit tests.&quot;</em>&#160; Does that mean that you have time to debug your application by stepping through hundreds of lines of code?&#160; Do you have time to litter your code with printf()s hoping to track down where a variable gets set to null?&#160; Maybe we&#8217;re just too used to the Edit-Build-Debug Cycle taking minutes for each iteration, waiting for ASP.NET to finish compiling its pages so we can navigate to where the problem is, enter what we think the bad data is, click a button, and then start hitting breakpoints&#8230; lather, rinse, repeat, for hours on end.</p>
<p>So when the project gets to the end of the timeline and budget, and the result is buggy, and we&#8217;re breaking more things with each deployment because of regression issues, and the client starts saying things like &quot;this project is a total failure,&quot; and the project manager is demanding that everyone start putting in all-nighters to deal with the bug list &#8230; is that better than an alternative of spending a little bit more time up front on writing easily-tested code?&#160; </p>
<p>So, how about we strike a pragmatic agreement &#8211; identify a difficult part of an application you&#8217;re working on, and figure out how to write unit tests for it.&#160; I&#8217;m not even talking about &quot;test first&quot; or &quot;100% test coverage,&quot; just write something to make it easier to confirm that the behavior of this code is correct.&#160; At least identify the parts of your code that stand in the way of tests &#8211; its almost always database or web-dependencies, and is an indicator of further problems, but we&#8217;re taking baby steps here.&#160; See how that goes, and see what you can learn from it.</p>
<p>I await your flames in the comments&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/05/20/get-started-writing-testable-code/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Thanks to BDD</title>
		<link>http://elegantcode.com/2008/05/01/thanks-to-bdd/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=thanks-to-bdd</link>
		<comments>http://elegantcode.com/2008/05/01/thanks-to-bdd/#comments</comments>
		<pubDate>Thu, 01 May 2008 18:49:48 +0000</pubDate>
		<dc:creator>Alex Mueller</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[Testing/QA]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/05/01/thanks-to-bdd/</guid>
		<description><![CDATA[I have been doing code reviews frequently this past week and have been remarking on the naming conventions of test methods. In a effort to try and find the rules of BDD naming conventions, I came across Dan North&#8217;s introduction to BDD, which is a great starting point, and a blog post by David Laribee [...]]]></description>
			<content:encoded><![CDATA[<p>I have been doing code reviews frequently this past week and have been remarking on the naming conventions of test methods. In a effort to try and find the rules of BDD naming conventions, I came across <a title="Dan North&#39;s introduction to BDD" href="http://dannorth.net/introducing-bdd" target="_blank">Dan North&#8217;s introduction to BDD</a>, which is a great starting point, and a blog post by <a title="David Laribee" href="http://codebetter.com/blogs/david_laribee/archive/2007/12/17/approaching-bdd.aspx" target="_blank">David Laribee</a> that has made a good impression on me. You can read up on BDD to learn more, this post will not go into detail about it. </p>
<p>From what I gathered from David Laribee&#8217;s <a title="article" href="http://codebetter.com/blogs/david_laribee/archive/2007/12/17/approaching-bdd.aspx" target="_blank">article</a>, I like this. I REALLY like this. </p>
<p><img src="http://codebetter.com/blogs/david_laribee/WindowsLiveWriter/ApproachingBDD_AED1/resharper-specs_3.jpg" /> </p>
<p>By changing namespace, class, and method names, the behavior of each spec (test) is clearly revealed. In a larger suite of tests, if there are failures, I can more easily see what is failing and what trends, if any, are resulting in my failures. Before, I would name my test method names to describe a behavior, &quot;Some concept should do this when given that.&quot; Getting the namespace and class name involved provides a more legible test result. </p>
<p>While reviewing a test case for a peer, I took this approach and arrived at the following scenario. I am changing the names of the methods to hide details. The original test method was &quot;FilterToEndPointTestReport.&quot; Making this more readable, using my previous approach, we arrived at &quot;FilterShouldUpdateStatusOnReportWhenDefaultFilterValueIsChanged.&quot; Great, that is better, but&#8230;</p>
<p>Applying the approach described in David&#8217;s post, I now have this.</p>
<div style="border-right: gray 1px solid; padding-right: 4px; padding-left: 4px; font-size: 8pt; border-top: gray 1px solid; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">namespace</span> Specs_for_Filters</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>   <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> When_default_filter_value_is_changed : FilterTestFixture</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>   {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     [Test]</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Endpoint_should_be_updated_on_report {}</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>     </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>     [Test]</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Endpoint_should_be_updated_on_grid {}</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>     </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>     [Test]</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Endpoint_should_be_updated_on_chart {}</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>   }</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>   </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>   <span style="color: #0000ff">public</span> <span style="color: #0000ff">abstract</span> <span style="color: #0000ff">class</span> FilterTestFixture</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>   {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span>     <span style="color: #008000">// provide common functionality that will be used </span></pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span>     <span style="color: #008000">// among behavior-driven filter test classes.</span></pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span>   }</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span> }</pre>
</p></div>
</div>
<p>When my tests run, their resulting output is more legible. This approach helps me to think about my tests in terms of behavior rather than implementation. In my opinion, my test cases are now more abstract and more succinct. </p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/05/01/thanks-to-bdd/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Alt.Net Seattle &#8211; Takeaway&lt;DDDD&gt;().Resources</title>
		<link>http://elegantcode.com/2008/04/30/altnet-seattle-takeawayddddresources/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=altnet-seattle-takeawayddddresources</link>
		<comments>http://elegantcode.com/2008/04/30/altnet-seattle-takeawayddddresources/#comments</comments>
		<pubDate>Thu, 01 May 2008 03:22:10 +0000</pubDate>
		<dc:creator>Jarod Ferguson</dc:creator>
				<category><![CDATA[alt.net]]></category>
		<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/04/30/altnet-seattle-takeawayddddresources/</guid>
		<description><![CDATA[As other attendees have alluded to, one of the better questions from that came from the session was &#8220;How do you move a team that&#8217;s used to working with a request/response architecture to a domain driven messaged based architecture?&#8221; I thought Martin Fowler answered the question very well: &#8220;Anything that causes a state change to [...]]]></description>
			<content:encoded><![CDATA[<p>As other attendees have alluded to, one of the better questions from that came from the <a href="http://elegantcode.com/2008/04/27/altnet-seattle-takeawayddddvideo/">session</a> was &#8220;How do you move a team that&#8217;s used to working with a request/response architecture to a domain driven messaged based architecture?&#8221;</p>
<p><span id="more-1125"></span></p>
<p>I thought Martin Fowler answered the question very well:
<p><em>&#8220;Anything that causes a state change to my world, my domain model… I capture in an object, you can think of it as a command object, I like to think of it as an event object. That object carries with it all the information about the kind of state change it might be. Then I have some way of processing it against my domain model to actually perform the change, but I still store and persist that event object as part of the record of what I’ve done.” DDDD video, 49:00ish</em>
<p>He are a couple of great articles from Martin&#8217;s site which elaborate on his statement, if you are interested in making the transition from request/response to messaging I recommend giving them both a thorough read. I am currently in the process of making the transition myself and I found them very helpful.
<p><a href="http://www.martinfowler.com/eaaDev/EventSourcing.html">Fowler &#8211; Event Sourcing</a></p>
<p><a href="http://www.martinfowler.com/eaaDev/EventCollaboration.html">Fowler &#8211; Event Collaboration</a>
<p>&nbsp;
<p>Also from the session came a great list of other reading materials, so bone up!
<p><a href="http://www.google.com/search?hl=en&amp;q=Pattern+Oriented+Software+Architecture&amp;btnG=Search">Pattern Oriented Software Architecture Books 1-4</a>
<p><a href="http://www.amazon.com/Distributed-Event-Based-Systems-Gero-M%C3%BChl/dp/3540326510/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1208908666&amp;sr=1-1">Enterprise Integration Patterns</a>&nbsp;
<p><a href="http://www.amazon.com/Distributed-Event-Based-Systems-Gero-M%C3%BChl/dp/3540326510/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1208908666&amp;sr=1-1">Domain Driven Design</a>&nbsp;
<p><a href="http://www.infoq.com/news/2006/12/domain-driven-design" target="_blank">Domain Driven Design Quickly</a> (Free 100 page compressed version in PDF provided by InfoQ)
<p><a href="http://www.amazon.com/Power-Events-Introduction-Processing-Distributed/dp/0201727897/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1208908750&amp;sr=1-1">Power of Events</a>
<p><a href="http://www.amazon.com/Distributed-Event-Based-Systems-Gero-M%C3%BChl/dp/3540326510/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1208908666&amp;sr=1-1">Distributed Event Based Systems</a>
<p><a href="http://www.amazon.com/Event-Based-Programming-Taking-Events-Limit/dp/1590596439">Event Based Programming</a>
<p><a href="http://www.amazon.com/Software-Architecture-Practice-Len-Bass/dp/0201199300">Software Architecture in Practice (weighing &#8216;ilities&#8217;)</a>
<p><a href="http://www.sei.cmu.edu/pub/documents/95.reports/pdf/tr021.95.pdf">SEI &#8211; Quality Attributes</a> (PDF)
<p>&nbsp;
<p>Thanks to all the attendees including <a href="http://www.lostechies.com/blogs/evan_hoff/">Evan Hoff</a>, <a href="http://udidahan.weblogs.us/">Udi Dahan</a> and <a href="http://codebetter.com/blogs/gregyoung/">Greg Young</a> for helping compile the great list of books you see above. (as well as their contributions to the conversation in general) </p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/04/30/altnet-seattle-takeawayddddresources/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Alt.Net Seattle &#8211; Takeaway&lt;DDDD&gt;().Video</title>
		<link>http://elegantcode.com/2008/04/27/altnet-seattle-takeawayddddvideo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=altnet-seattle-takeawayddddvideo</link>
		<comments>http://elegantcode.com/2008/04/27/altnet-seattle-takeawayddddvideo/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 08:56:25 +0000</pubDate>
		<dc:creator>Jarod Ferguson</dc:creator>
				<category><![CDATA[alt.net]]></category>
		<category><![CDATA[Architecture and Design]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/04/27/altnet-seattle-takeawayddddvideo/</guid>
		<description><![CDATA[This last weekend (yes, a week ago I know) at Alt.Net I had the opportunity to convene a session on DDDD.&#160; (which was also joined with Event Driven Architecture and one other messaging related topic) The open spaces format makes it easy for whoever is there, to talk about whatever they want. DDDD, or distributed [...]]]></description>
			<content:encoded><![CDATA[<p>This last weekend (yes, a week ago I know) at Alt.Net I had the opportunity to convene a session on DDDD.&nbsp; (which was also joined with Event Driven Architecture and one other messaging related topic)
<p>The open spaces format makes it easy for whoever is there, to talk about whatever they want. DDDD, or distributed message base systems in general, was exactly what I wanted to talk about. This was my first open spaces conference, so I was a little nervous to be convening in front of highly respected peers. Luckily with all the tremendous talent in the room, being the convener for DDDD was about as complicated as finding a Starbucks in Seattle. I also learned the golden rule of open spaces, which is &#8211; if all else fails&#8230; turn it into a fishbowl.
<p>Part of the responsibility of the convener is to provide a take away of what was talked about. Unfortunately given the magnitude of the topic, and my hectic schedule, I am sitting here 1 week later looking at 4 pages of thoughts and no real way to comprise what’s in my head. So my solution is to break it up into a series of posts just to get something out there.
<p>So let’s start with the <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/25/altdotnet-seattle-session-video.aspx" target="_blank">video</a>. The conversation is very dense, and is packed full of great info. Some of what is said is hard to follow without context, so I challenge you, if you are interested in the topic to listen to it several times. Even after being in the room, the 3<sup>rd</sup> time I watched the video I was still learning more and more.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/04/27/altnet-seattle-takeawayddddvideo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DTO&#8217;s or Serialized Domain Entities?</title>
		<link>http://elegantcode.com/2008/04/27/dtos-or-serialized-domain-entities/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dtos-or-serialized-domain-entities</link>
		<comments>http://elegantcode.com/2008/04/27/dtos-or-serialized-domain-entities/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 08:09:02 +0000</pubDate>
		<dc:creator>Jarod Ferguson</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[Design Patterns]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/04/27/dtos-or-serialized-domain-entities/</guid>
		<description><![CDATA[I hear this question come up time and time again. It is something that I have been dealing with for a while now, and have some experience with doing both ways. I started writing this in response to a DDD thread, but it got rather large and so I turned it into a post. So [...]]]></description>
			<content:encoded><![CDATA[<p>I hear this question come up time and time again. It is something that I have been dealing with for a while now, and have some experience with doing both ways. I started writing this in response to a <a href="http://tech.groups.yahoo.com/group/domaindrivendesign/message/7286" target="_blank">DDD thread</a>, but it got rather large and so I turned it into a post. So here ya go!
<p>I think you have to write DTO&#8217;s for any sort of long term Enterprise &#8216;system of systems&#8217; solution. I fought this for some time, but since moving to an Assembler/DTO I much enjoy the freedom of being able to easily tweak my DTO &#8220;snapshot&#8221; of the aggregate root I am working with. Maintaining them is very little overhead.
<p>I tend to think of the DTO as a message, a value object. This is necessary because once an entity leaves the boundary it can no longer function within its original meaning. Its methods may be intended to only run within a given context, which is not the same once on another tier. (Things like lazy loading are a good example) Once the DTO/Message arrives to the caller, it very well may (and probably should) be translated/assembled into another model which can represent its new semantics.
<p>Some other advantages of DTO w/ Assembler or Builder:<br />-Can explicitly control the depth of the graph/tree you are serializing.<br />-Can flatten out the data where needed<br />-Can return significantly less data (maybe you only need 3 fields instead of 15)<br />-Not tightly coupled between remote boundaries (this could be a mess when working with a large team)<br />-Interoperable
<p>I wrote a post a while back showing a way to &#8216;<a href="http://elegantcode.com/2007/12/05/fun-with-generics-from-repository-to-dto/" target="_blank">templatize</a>&#8216; the process. My current implementations are much different with LINQ now, but maybe it could stimulate some ideas for whomever.
<p><em>The next thing I would like to do is remove the assembler altogether. By flagging fields with attributes or using config to specify a mapping, I could then feed <a href="http://blogs.msdn.com/meek/archive/2008/04/25/using-linq-expressions-to-generate-dynamic-methods.aspx" target="_blank">dynamic methods</a> and run a translation/builder strategy.</em>
<p>I know there are concerns about writing and maintaining assembler and DTO, but to me this is the least of the worry, a more challenging scenario would be the UnitOfWork (How to you intended to track remote state, concurrency etc) How about versioning? performance? scala.. well ilities in general?
<p>These kinds of problems lead one from Request/Response, Patterns of Enterprise Architecture &amp; DDD to a Pub/Sub Message Bus &#8211; Enterprise Integration Patterns &amp; DDDD.
<p>And to think all you want to do is send some frickin entities to a remote client&nbsp; <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/04/27/dtos-or-serialized-domain-entities/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Removing Duplicate Code in Functions</title>
		<link>http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=removing-duplicate-code-in-functions</link>
		<comments>http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 04:06:40 +0000</pubDate>
		<dc:creator>Alex Mueller</dc:creator>
				<category><![CDATA[Architecture and Design]]></category>
		<category><![CDATA[Testing/QA]]></category>
		<category><![CDATA[Tools and Utilities]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/</guid>
		<description><![CDATA[Duplicate code to me is wrong. Writing duplicate code to me is like using poor grammar. If I am unaware of it, I am none the wiser. However, if I knowingly use poor grammar or duplicate code, I feel bad. After seeing too many duplications across methods in one or more classes, I decided to [...]]]></description>
			<content:encoded><![CDATA[<p>Duplicate code to me is wrong. Writing duplicate code to me is like using poor grammar. If I am unaware of it, I am none the wiser. However, if I knowingly use poor grammar or duplicate code, I feel bad.</p>
<p>After seeing too many duplications across methods in one or more classes, I decided to investigate a way to remove these. I am always looking to remove duplicate code, even code that shares similarities, I look to refator. Removing duplications is important to adapt more easily to change. When a code change is required, we should only have to make it in one place. The following article will show two relatively simple means to address this code smell, delegates and an Aspect-Oriented approach.</p>
<p>The example I am using in this article is seen below. It is a unit test class, StackFixture class, and it is extremely trivial. This is a typical unit test taken from <a target="_blank" href="http://www.amazon.com/Test-Driven-Development-Microsoft-NET-Professional/dp/0735619484/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1207679353&amp;sr=8-1" title="Test-Driven Development in Microsoft .NET">Test-Driven Development in Microsoft .NET</a>. I have added the logging functionality as an easy means to show how these types of DRY violations can occur. While the duplications in this example deal with logging, they could pertain to other, more complex, functionality as well. The approaches to removing duplications across methods in this article can work with these simple scenarios, as well as more complex ones.</p>
<p>Take for example this sample test case. Each test method logs a message before and after executing the test logic. This violates DRY. We want to keep our test logic in our method, but factor out the duplicate logging. Again, if we were not logging, but doing some repetitive logic, we could factor that out as well.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [TestFixture]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> StackFixture : AbstractBaseFixture</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">private</span> Stack stack;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     [SetUp]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SetUp()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>         stack = <span style="color: #0000ff">new</span> Stack();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  12:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  13:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Empty()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  14:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  15:</span>         Log.Info(<span style="color: #006080">"Starting Empty test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  16:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  17:</span>         Assert.IsTrue(stack.IsEmpty);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  18:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  19:</span>         Log.Info(<span style="color: #006080">"Ending Empty test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  20:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  21:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  22:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  23:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> PushOne()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  24:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  25:</span>         Log.Info(<span style="color: #006080">"Starting PushOne test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  26:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  27:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  28:</span>         Assert.IsFalse(stack.IsEmpty, <span style="color: #006080">"After Push, IsEmpty should be false."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  29:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  30:</span>         Log.Info(<span style="color: #006080">"Ending PushOne test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  31:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  32:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  33:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  34:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Pop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  35:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  36:</span>         Log.Info(<span style="color: #006080">"Starting Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  37:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  38:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  39:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  40:</span>         Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  41:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  42:</span>         Log.Info(<span style="color: #006080">"Ending Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  43:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  44:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  45:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  46:</span>     [ExpectedException(<span style="color: #0000ff">typeof</span>(InvalidOperationException))]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  47:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> PopEmptyStack()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  48:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  49:</span>         Log.Info(<span style="color: #006080">"Starting PopEmptyStack test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  50:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  51:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  52:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  53:</span>         Log.Info(<span style="color: #006080">"Ending PopEmptyStack test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  54:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  55:</span> }</pre>
<p><strong>Remove Duplications with Delegates</strong></p>
<p>Quite simply, we can remove our method duplications using a delegate, in this case, the <a target="_blank" href="http://msdn2.microsoft.com/en-us/library/system.action.aspx" title="System.Action delegate">System.Action delegate</a>. Thanks to <a target="_blank" href="http://www.ayende.com/" title="Ayende">Ayende</a> for helping me understand this option. We create a method, TestMethod (as shown below), and add it to our StackFixture class. The method takes two strings (string beforeMessage and string afterMessage) and the Action delegate, representing the test method logic. We will call this method within our test cases.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestMethod(<span style="color: #0000ff">string</span> beforeMessage, <span style="color: #0000ff">string</span> afterMessage, Action action)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span>     <span style="color: #008000">// before</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     Log.Info(beforeMessage);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     <span style="color: #008000">// invoke our method</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     action();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>     <span style="color: #008000">// after</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>     Log.Info(afterMessage);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> }</pre>
<p>Then, in our tests, we replace the following test method&#8230;</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Pop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     Log.Info(<span style="color: #006080">"Starting Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>     Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>     Log.Info(<span style="color: #006080">"Ending Pop test"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> }</pre>
<p>With the same method using our delegate approach.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Pop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     TestMethod(<span style="color: #006080">"Starting Pop test"</span>, <span style="color: #006080">"Ending Pop test"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span>                <span style="color: #0000ff">delegate</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>                    {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>                        stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>                        stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>                        Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span>                    });</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span> }</pre>
<p>We can replace each of our test methods with the same TestMethod using the <a target="_blank" href="http://msdn2.microsoft.com/en-us/library/system.action.aspx" title="System.Action delegate">System.Action delegate</a>. It will then easy to omit our before and after strings replacing them with &#8220;action.Method.Name,&#8221; or some other intelligent logic to determine what to log.</p>
<p>This approach works well, but delegates are often difficult to understand. If this solution suits your needs, make sure the implementation is easily maintainable. What is nice about this approach is how simple it is. There is no need to reference any assemblies outside of the .Net framework, i.e. no third party dependencies.</p>
<p><strong>The Aspect-Oriented Approach</strong></p>
<p><a target="_blank" href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" title="Aspect-Oriented Programming">Aspect-Oriented Programming</a> (AOP) is an entirely different animal. It certainly deserves more than just a blog post. Please read more about it online. This article will not explain the details of AOP.</p>
<p>If you are reading this, welcome back. I will assume you are now familiar with AOP. There are several options for AOP frameworks. Some frameworks I have used are <a target="_blank" href="http://www.springframework.net/" title="Spring.net">Spring.net</a>, <a target="_blank" href="http://www.castleproject.org/" title="Castle Project">Castle Project</a>, and <a target="_blank" href="http://www.postsharp.org/" title="PostSharp">PostSharp</a>. The former two provide IoC capabilities as well. I suggest using a well-supported framework, one with community support and frequent updates. Investigate for yourself, there are several nice options available.</p>
<p><strong>AOP with Castle DynamicProxy</strong></p>
<p><a target="_blank" href="http://hammett.castleproject.org/" title="Hamilton Verissimo">Hamilton Verissimo</a> put together a good <a target="_blank" href="http://www.codeproject.com/KB/cs/hamiltondynamicproxy.aspx" title="sample using Castle's DynamicProxy">sample using Castle&#8217;s DynamicProxy</a>. It is a nice, clean implementation.This worked fine for me and would work well in other situations. However, in my scenario, if I were to use this approach, I needed to have each of my test classes extend from MarshalByRef. In addition, I would need to modify the underlying NUnit framework to create my proxies in order to provide advice. Since I could not do the latter, or did not want to investigate, I searched for other AOP options.</p>
<p>The DynamicProxy aproach to solving your AOP needs is a great option. It just did not work in my situation, only because NUnit executes each of my methods. I would need to somehow intercept the creation of my test class, create a proxy of it, and execute the test methods on it.</p>
<p><strong>AOP with PostSharp</strong></p>
<p><a target="_blank" href="http://www.postsharp.org" title="Gael Fraiteur's PostSharp">Gael Fraiteur&#8217;s PostSharp</a> is a great option for AOP needs. It is extremely clean and easy to use. It is the simplest AOP framework I have used. I suggest watching Gael&#8217;s <a target="_blank" href="http://www.postsharp.org/about/video/" title="video tutorial">video tutorial</a>.</p>
<p>The first thing I needed to do, besides downloading and installing PostSharp, is to add two references to my project, PostSharp.Laos and PostSharp.Public. After that, I create a simple class extending OnMethodInvocationAspect, called LoggingMethodInvocationAspect.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [Serializable]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">sealed</span> <span style="color: #0000ff">class</span> LoggingMethodInvocationAspect : OnMethodInvocationAspect</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">private</span> ILogger log;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span>     <span style="color: #0000ff">public</span> LoggingMethodInvocationAspect(ILogger logger)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span>         log = logger;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnInvocation(MethodInvocationEventArgs eventArgs)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  12:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  13:</span>         <span style="color: #008000">// before</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  14:</span>         log.Info(<span style="color: #006080">"OnInvocation Before proceed"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  15:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  16:</span>         <span style="color: #008000">// invoke</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  17:</span>         eventArgs.Proceed();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  18:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  19:</span>         <span style="color: #008000">// after</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  20:</span>         log.Info(<span style="color: #006080">"OnInvocation After proceed"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  21:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  22:</span> }</pre>
<p>At this point, all we need to do is apply our aspect on target methods. The &#8220;AttributeTargetMembers&#8221; attribute can use wildcards. This tells the AOP framework to only intercept those methods in the &#8220;MathService&#8221; class that start with &#8220;Test.&#8221; Below is the sample where I specify the target assembly, target type (class or classes to intercept), and target methods to intercept. There are many features beyond what I am showing so do further investigation.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [assembly: ClassLibrary.SampleInterfaces.LoggingMethodInvocationAspect(</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span>     AttributeTargetAssemblies = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span>     AttributeTargetTypes = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox.MathService"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>     AttributeTargetMembers = <span style="color: #006080">"Test*"</span>)]</pre>
<p>Finally, my StackFixture class now looks something like this. Notice that the duplicate logging logic is now removed and each test method is prefixed with &#8220;Test&#8221; in the method name. This is so that PostSharp can filter what methods to intercept.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   1:</span> [assembly: ClassLibrary.SampleInterfaces.LoggingMethodInvocationAspect(</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   2:</span>   AttributeTargetAssemblies = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   3:</span>   AttributeTargetTypes = <span style="color: #006080">"ClassLibrary.UnitTesting.Sandbox.MathService"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   4:</span>   AttributeTargetMembers = <span style="color: #006080">"Test*"</span>)]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   5:</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   6:</span> [TestFixture]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   7:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> StackFixture</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">   8:</span> {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">   9:</span>     <span style="color: #0000ff">private</span> Stack stack;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  10:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  11:</span>     [SetUp]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  12:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> SetUp()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  13:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  14:</span>         stack = <span style="color: #0000ff">new</span> Stack();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  15:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  16:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  17:</span>     [TearDown]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  18:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TearDown(){}</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  19:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  20:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  21:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestEmpty()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  22:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  23:</span>         Assert.IsTrue(stack.IsEmpty);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  24:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  25:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  26:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  27:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestPushOne()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  28:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  29:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  30:</span>         Assert.IsFalse(stack.IsEmpty, <span style="color: #006080">"After Push, IsEmpty should be false."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  31:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  32:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  33:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  34:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestPop()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  35:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  36:</span>         stack.Push(<span style="color: #006080">"first element"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  37:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  38:</span>         Assert.IsTrue(stack.IsEmpty, <span style="color: #006080">"After Push - Pop, IsEmpty should be true."</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  39:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  40:</span> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  41:</span>     [Test]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  42:</span>     [ExpectedException(<span style="color: #0000ff">typeof</span>(InvalidOperationException))]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  43:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestPopEmptyStack()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  44:</span>     {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  45:</span>         stack.Pop();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #606060">  46:</span>     }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #606060">  47:</span> }</pre>
<p>The end result, a StackFixture test class with duplicate logging logic removed. The PostSharp AOP framework post-processes the compiled assembly and inserts itself, easily providing points of interception.</p>
<p>The PostSharp approach does involve a third-party dependency, but I feel like it is cleaner than the delegate approach. Gael informed me future versions of PostSharp will provide a more configurable solution than adding the [assembly ...] reference for the aspects, perhaps an XML configuration option. This can be done today, but involves some work.</p>
<p>Whether you use delegates, AOP, or some other approach, remove duplicate code wherever possible. I am happy to use either approach in my projects. There are tradeoffs to either solution, so investigate for yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2008/04/08/removing-duplicate-code-in-functions/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

