<?xml version="1.0" encoding="iso-8859-1"?><!-- generator="b2evolution/4.0.3" -->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Architecture, Design &#38; Strategy - Author(s): Eli Weinstock-Herman (tarwn)</title>
		<link>http://blogs.lessthandot.com/index.php/Architect/</link>
		<atom:link rel="self" type="application/rss+xml" href="http://blogs.lessthandot.com/index.php/Architect/?tempskin=_rss2" />
		<description></description>
		<language>en-GB</language>
		<docs>http://blogs.law.harvard.edu/tech/rss</docs>
		<admin:generatorAgent rdf:resource="http://b2evolution.net/?v=4.0.3"/>
		<ttl>60</ttl>
				<item>
			<title>Scalability is Easy! (To Get Wrong)</title>
			<link>http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/scalability-is-easy-to-get</link>
			<pubDate>Wed, 05 Dec 2012 12:50:00 +0000</pubDate>			<dc:creator>Eli Weinstock-Herman (tarwn)</dc:creator>
			<category domain="main">Designing Software</category>			<guid isPermaLink="false">1923@http://blogs.lessthandot.com/</guid>
						<description>&lt;p&gt;Scalability is easy, provided you don&#039;t need it to work.&lt;/p&gt;

&lt;p&gt;Probably the number one failure of system scaling is when people dive right in and start building. No baselines, limited measurements, no analysis, just a hypothesis and a whole lot of late nights tweaking the system. With extra complexity comes extra costs, from the initial development through more expensive maintenance. Scale poorly and not only do we take on those extra complexity costs, but also the more obvious additional costs of the actual implementation (new servers, more resources, etc).&lt;/p&gt;

&lt;h2&gt;The Somewhat Contrived Example&lt;/h2&gt;

&lt;p&gt;Recently I&#039;ve been working on a system to simulate parallelizing workloads, specifically workloads that depend on external resources with rate or load thresholds. Let&#039;s use it to look at a somewhat contrived example.&lt;/p&gt;

&lt;div style=&quot;background-color: #eeeeee; padding: 1em; margin: 1em;&quot;&gt;
Note: For this post, the simulated &quot;service&quot; has a 100 request/minute limit and throttles individual clients for 15 second windows. Individual operations consist of 50ms of local processing and a single service request that has 50ms of latency and 100 ms for processing and response time. Similar results can be achieved with more realistic batch sizes and rates, the smaller values just allow me to more quickly produce samples for the blog post.
&lt;/div&gt;

&lt;p&gt;So the backstory is that I have a batch process that is running more and more slowly as we take on larger and more frequent workloads. &lt;/p&gt;

&lt;p&gt;I start by testing the batch process locally so I can see how slow it is before I make changes.&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_01.png&quot; alt=&quot;Graph - 1 Client, 60 Requests, 100rpm Limit&quot; /&gt;&lt;br /&gt;
	1 Client, 60 Requests, 100rpm
&lt;/div&gt;

&lt;p&gt;Locally it runs pretty quickly, but I&#039;m betting that parallelizing the process will give me a significant increase in speed.&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_02.png&quot; alt=&quot;Graph - 1 Client vs 30 Clients, 60 Requests, 100rpm Limit&quot; /&gt;&lt;br /&gt;
	1 Client vs 30 Clients, 60 Requests, 100rpm
&lt;/div&gt;

&lt;p&gt;Look how well that performance improved, I achieved better than a 6x improvement in performance. My job here is done. &lt;/p&gt;

&lt;p&gt;Except when I try to push this to production, I start getting a lot of errors. &lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_03.png&quot; alt=&quot;Graph - 30 Clients, 300 Requests, 100rpm - 67% Failure Rate&quot; /&gt;&lt;br /&gt;
	30 Clients, 300 Requests, 100rpm - 67% Failure Rate
&lt;/div&gt;

&lt;p&gt;As it turns out, the external API my process saves the data to has a rate limit. When I exceed the allowable rate, I&#039;m throttled for a short period of time. Any requests I make during that throttle period are returned with errors indicating I&#039;m throttled.&lt;/p&gt;

&lt;p&gt;Hmm. Luckily there are a number of common patterns available to retry these types of failures. I&#039;ll add an exponential back-off retry pattern so that when I get throttled my service will retry failed requests at slower rates until the service un-throttles me. While I&#039;ve found plenty of code examples online, none of them seem to have recommendations, so I&#039;ll just use one of the sample settings they provide.&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_04.png&quot; alt=&quot;Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #1 - 7% Failure Rate&quot; /&gt;&lt;br /&gt;
	30 Clients, 300 Requests, 100rpm, Retry Policy #1 - 7% Failure Rate
&lt;/div&gt;

&lt;p&gt;Hmm, better. My failure rate has gone way down. What if I tweak the values?&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_05.png&quot; alt=&quot;Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #2 - 29% Failure Rate&quot; /&gt;&lt;br /&gt;
	30 Clients, 300 Requests, 100rpm, Retry Policy #2 - 29% Failure Rate
&lt;/div&gt;

&lt;p&gt;Oh, that was bad, I obviously was on the right track before. What if I just extend the retry amount a bit to try and knock out the last bit of errors. &lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_06.png&quot; alt=&quot;Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #1B - 0% Failure Rate&quot; /&gt;&lt;br /&gt;
	30 Clients, 300 Requests, 100rpm, Retry Policy #1B - 0% Failure Rate
&lt;/div&gt;

&lt;p&gt;Ok, perfect. Now I have a system that is more than 6 times faster than the original, can be easily extended by throwing more workers at it, and is actually in a better position to handle occasional slow downs from my 3rd-party service. &lt;/p&gt;

&lt;p&gt;Success!&lt;/p&gt;

&lt;h2&gt;Where I Went Wrong&lt;/h2&gt;
&lt;p&gt;Ok, so maybe not. Over the course of my little story I went wrong in a number of places. Even though this was a contrived example, I&#039;ve watched very similar scenarios play out in a number of different organizations with real systems.&lt;/p&gt;

&lt;h3&gt;The Bottleneck&lt;/h3&gt;
&lt;p&gt;The first and most critical problem was that I didn&#039;t actually locate the bottleneck in my process, I simply tried to do more of the same. The &lt;a href=&quot;http://en.wikipedia.org/wiki/Theory_of_constraints&quot; title=&quot;Theory of Constraints at Wikipedia&quot;&gt;Theory of Constraints&lt;/a&gt; tells us that we can improve the rate of a process by identifying and exploiting the constraints. &lt;/p&gt;

&lt;p&gt;In this system, the constraint looked like it was the sequential execution of the tasks, but in reality the constraint was the time it took to call the 3rd-party API. Had we identified that bottleneck before starting, we could have approached the problem differently.&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/ProcessChange.png&quot; alt=&quot;Process - Alternative Design&quot; /&gt;&lt;br /&gt;
	Process - Alternative Design
&lt;/div&gt;

&lt;p&gt;Rather than the parallel complexity, we can modify how the tasks are executed to try and take advantage of knowing where our bottleneck is. If the API allowed us to submit several requests in a batch, this redesign would net us several orders of magnitude improvement. Another option would be to run the results of the local processing into a queue and submit requests from there at a slow trickle, using only a percentage of our API limit so as not to disrupt any other real-time operations or batch processing the system supports. Another option we could take advantage of is not starting any of our expensive 3rd-party communications until we know that the entire job can actually be processed successfully through our local process.&lt;/p&gt;

&lt;p&gt;Identifying the constraint unlocks the ability to turn the problem on it&#039;s head and achieve higher improvements, typically by orders of magnitude.&lt;/p&gt;

&lt;h3&gt;The Math Error&lt;/h3&gt;
&lt;p&gt;I concluded the scenario above by assuming I had found a good solution that also had a lot of headroom. Unfortunately what I actually did was find the ceiling. I have tuned the retry policy to 30 parallel systems, increasing that number could easily destabilize it further and cause more errors or delays. The headroom is, in fact, an illusion.&lt;/p&gt;

&lt;h3&gt;The Evolving Assumption&lt;/h3&gt;
&lt;p&gt;Somewhere along the way I found 30 clients to be a great improvement and didn&#039;t test other options. Then I made some assumptions about a retry policy. Then I tweaked that retry policy until the error rate disappeared. My assumptions made sense at the time, so I never questioned where they were leading me.&lt;/p&gt;

&lt;p&gt;When I found a winning combination for my retry rate, I didn&#039;t realize I was missing other, better options:&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_07.png&quot; alt=&quot;Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #1B vs 4A-C&quot; /&gt;&lt;br /&gt;
	30 Clients, 300 Requests, 100rpm, Retry Policy #1B vs 4A-C
&lt;/div&gt;

&lt;p&gt;What&#039;s worse, is that trail of assumptions along the way was never re-validated. I concluded with a 6.5x improvement, but is that still accurate?&lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666&quot;&gt;
	&lt;img src=&quot;http://tiernok.com/LTDBlog/Scalability/Graph_08.png&quot; alt=&quot;Graph - 1-50 Clients, 300 Requests, 100rpm, Retry Policy #1B&quot; /&gt;&lt;br /&gt;
	1-50 Clients, 300 Requests, 100rpm, Retry Policy #1B
&lt;/div&gt;

&lt;p&gt;When I run the same settings on a range of 1 to 50 clients, we can see that I lost that original 6x improvement along the way. All I have managed to do is add complexity and some very explicit costs for those additional systems.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Note: What happened to retry policy #3? Well originally 1B was actually named 3, then I decided to update the name halfway through the post but was too lazy to update all of the completed images. Oh well.&lt;/i&gt;&lt;/p&gt;

&lt;h2&gt;Scaling the Wrong Thing&lt;/h2&gt;
&lt;p&gt;This post used fairly small numbers, had I applied a larger workload, higher throughput rates, different throttling windows, the whole problem would have turned out differently. &lt;/p&gt;

&lt;p&gt;When we set out to make a system scale, we need to identify the real scenarios we are trying to scale for and the bottlenecks that stand in our way. Blindly performance tuning can look like an improvement, but is really just a poor short term investment that often entrenches the current performance problems even more deeply. There are a lot of questions that should be asked about the intended result, responsiveness fo the system, other operations it has to support while under load, potential overlap of that load, the type of load, etc. The patterns for one system may have relevance for another, but could just as easily be completely incorrect.&lt;/p&gt;

&lt;p&gt;How hard it is to scale a system is going to depend on a lot of factors. Getting it wrong just happens to be the easiest option.&lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/scalability-is-easy-to-get&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://lessthandot.com/&quot;&gt;LessThanDot&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Scalability is easy, provided you don't need it to work.</p>

<p>Probably the number one failure of system scaling is when people dive right in and start building. No baselines, limited measurements, no analysis, just a hypothesis and a whole lot of late nights tweaking the system. With extra complexity comes extra costs, from the initial development through more expensive maintenance. Scale poorly and not only do we take on those extra complexity costs, but also the more obvious additional costs of the actual implementation (new servers, more resources, etc).</p>

<h2>The Somewhat Contrived Example</h2>

<p>Recently I've been working on a system to simulate parallelizing workloads, specifically workloads that depend on external resources with rate or load thresholds. Let's use it to look at a somewhat contrived example.</p>

<div style="background-color: #eeeeee; padding: 1em; margin: 1em;">
Note: For this post, the simulated "service" has a 100 request/minute limit and throttles individual clients for 15 second windows. Individual operations consist of 50ms of local processing and a single service request that has 50ms of latency and 100 ms for processing and response time. Similar results can be achieved with more realistic batch sizes and rates, the smaller values just allow me to more quickly produce samples for the blog post.
</div>

<p>So the backstory is that I have a batch process that is running more and more slowly as we take on larger and more frequent workloads. </p>

<p>I start by testing the batch process locally so I can see how slow it is before I make changes.</p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_01.png" alt="Graph - 1 Client, 60 Requests, 100rpm Limit" /><br />
	1 Client, 60 Requests, 100rpm
</div>

<p>Locally it runs pretty quickly, but I'm betting that parallelizing the process will give me a significant increase in speed.</p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_02.png" alt="Graph - 1 Client vs 30 Clients, 60 Requests, 100rpm Limit" /><br />
	1 Client vs 30 Clients, 60 Requests, 100rpm
</div>

<p>Look how well that performance improved, I achieved better than a 6x improvement in performance. My job here is done. </p>

<p>Except when I try to push this to production, I start getting a lot of errors. </p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_03.png" alt="Graph - 30 Clients, 300 Requests, 100rpm - 67% Failure Rate" /><br />
	30 Clients, 300 Requests, 100rpm - 67% Failure Rate
</div>

<p>As it turns out, the external API my process saves the data to has a rate limit. When I exceed the allowable rate, I'm throttled for a short period of time. Any requests I make during that throttle period are returned with errors indicating I'm throttled.</p>

<p>Hmm. Luckily there are a number of common patterns available to retry these types of failures. I'll add an exponential back-off retry pattern so that when I get throttled my service will retry failed requests at slower rates until the service un-throttles me. While I've found plenty of code examples online, none of them seem to have recommendations, so I'll just use one of the sample settings they provide.</p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_04.png" alt="Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #1 - 7% Failure Rate" /><br />
	30 Clients, 300 Requests, 100rpm, Retry Policy #1 - 7% Failure Rate
</div>

<p>Hmm, better. My failure rate has gone way down. What if I tweak the values?</p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_05.png" alt="Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #2 - 29% Failure Rate" /><br />
	30 Clients, 300 Requests, 100rpm, Retry Policy #2 - 29% Failure Rate
</div>

<p>Oh, that was bad, I obviously was on the right track before. What if I just extend the retry amount a bit to try and knock out the last bit of errors. </p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_06.png" alt="Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #1B - 0% Failure Rate" /><br />
	30 Clients, 300 Requests, 100rpm, Retry Policy #1B - 0% Failure Rate
</div>

<p>Ok, perfect. Now I have a system that is more than 6 times faster than the original, can be easily extended by throwing more workers at it, and is actually in a better position to handle occasional slow downs from my 3rd-party service. </p>

<p>Success!</p>

<h2>Where I Went Wrong</h2>
<p>Ok, so maybe not. Over the course of my little story I went wrong in a number of places. Even though this was a contrived example, I've watched very similar scenarios play out in a number of different organizations with real systems.</p>

<h3>The Bottleneck</h3>
<p>The first and most critical problem was that I didn't actually locate the bottleneck in my process, I simply tried to do more of the same. The <a href="http://en.wikipedia.org/wiki/Theory_of_constraints" title="Theory of Constraints at Wikipedia">Theory of Constraints</a> tells us that we can improve the rate of a process by identifying and exploiting the constraints. </p>

<p>In this system, the constraint looked like it was the sequential execution of the tasks, but in reality the constraint was the time it took to call the 3rd-party API. Had we identified that bottleneck before starting, we could have approached the problem differently.</p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/ProcessChange.png" alt="Process - Alternative Design" /><br />
	Process - Alternative Design
</div>

<p>Rather than the parallel complexity, we can modify how the tasks are executed to try and take advantage of knowing where our bottleneck is. If the API allowed us to submit several requests in a batch, this redesign would net us several orders of magnitude improvement. Another option would be to run the results of the local processing into a queue and submit requests from there at a slow trickle, using only a percentage of our API limit so as not to disrupt any other real-time operations or batch processing the system supports. Another option we could take advantage of is not starting any of our expensive 3rd-party communications until we know that the entire job can actually be processed successfully through our local process.</p>

<p>Identifying the constraint unlocks the ability to turn the problem on it's head and achieve higher improvements, typically by orders of magnitude.</p>

<h3>The Math Error</h3>
<p>I concluded the scenario above by assuming I had found a good solution that also had a lot of headroom. Unfortunately what I actually did was find the ceiling. I have tuned the retry policy to 30 parallel systems, increasing that number could easily destabilize it further and cause more errors or delays. The headroom is, in fact, an illusion.</p>

<h3>The Evolving Assumption</h3>
<p>Somewhere along the way I found 30 clients to be a great improvement and didn't test other options. Then I made some assumptions about a retry policy. Then I tweaked that retry policy until the error rate disappeared. My assumptions made sense at the time, so I never questioned where they were leading me.</p>

<p>When I found a winning combination for my retry rate, I didn't realize I was missing other, better options:</p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_07.png" alt="Graph - 30 Clients, 300 Requests, 100rpm, Retry Policy #1B vs 4A-C" /><br />
	30 Clients, 300 Requests, 100rpm, Retry Policy #1B vs 4A-C
</div>

<p>What's worse, is that trail of assumptions along the way was never re-validated. I concluded with a 6.5x improvement, but is that still accurate?</p>

<div style="text-align: center; font-size: .8em; color: #666666">
	<img src="http://tiernok.com/LTDBlog/Scalability/Graph_08.png" alt="Graph - 1-50 Clients, 300 Requests, 100rpm, Retry Policy #1B" /><br />
	1-50 Clients, 300 Requests, 100rpm, Retry Policy #1B
</div>

<p>When I run the same settings on a range of 1 to 50 clients, we can see that I lost that original 6x improvement along the way. All I have managed to do is add complexity and some very explicit costs for those additional systems.</p>

<p><i>Note: What happened to retry policy #3? Well originally 1B was actually named 3, then I decided to update the name halfway through the post but was too lazy to update all of the completed images. Oh well.</i></p>

<h2>Scaling the Wrong Thing</h2>
<p>This post used fairly small numbers, had I applied a larger workload, higher throughput rates, different throttling windows, the whole problem would have turned out differently. </p>

<p>When we set out to make a system scale, we need to identify the real scenarios we are trying to scale for and the bottlenecks that stand in our way. Blindly performance tuning can look like an improvement, but is really just a poor short term investment that often entrenches the current performance problems even more deeply. There are a lot of questions that should be asked about the intended result, responsiveness fo the system, other operations it has to support while under load, potential overlap of that load, the type of load, etc. The patterns for one system may have relevance for another, but could just as easily be completely incorrect.</p>

<p>How hard it is to scale a system is going to depend on a lot of factors. Getting it wrong just happens to be the easiest option.</p><div class="item_footer"><p><small><a href="http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/scalability-is-easy-to-get">Original post</a> blogged on <a href="http://lessthandot.com/">LessThanDot</a>.</small></p></div>]]></content:encoded>
								<comments>http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/scalability-is-easy-to-get#comments</comments>
			<wfw:commentRss>http://blogs.lessthandot.com/index.php/Architect/?tempskin=_rss2&#38;disp=comments&#38;p=1923</wfw:commentRss>
		</item>
				<item>
			<title>Adding User Emulation to an Application</title>
			<link>http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/adding-user-emulation-to-an</link>
			<pubDate>Wed, 27 Apr 2011 12:57:00 +0000</pubDate>			<dc:creator>Eli Weinstock-Herman (tarwn)</dc:creator>
			<category domain="main">Designing Software</category>			<guid isPermaLink="false">1206@http://blogs.lessthandot.com/</guid>
						<description>&lt;p&gt;One of the tricks I picked up from my last job (and our forum software, now that I think of it) is the idea of user emulation. I could log into the application, search for a user, and, at the push of a button, temporarily become that user. The only differences between emulating them and actually logging in as them were a black bar that indicated who I am (with a link to stop emulating), all audit records continued to reflect my own user id, and I didn&#039;t need to keep track of 30 different sample accounts and passwords.&lt;/p&gt;

&lt;p&gt;As I said, it&#039;s a neat trick. &lt;/p&gt;

&lt;h2&gt;Advantages&lt;/h2&gt;
&lt;p&gt;Implemented consistently, this stops being just a trick and becomes a very powerful tool. Developers, QA, even customer service and support see benefits from being able to quickly emulate end users.&lt;/p&gt;

&lt;h3&gt;Debugging&lt;/h3&gt;
&lt;p&gt;As developers the largest benefit for us is the ability to debug our systems from a variety of viewpoints. Rather than going through the trouble of creating and managing sample users for every impacted role, we can use existing user records with real data behind them. This not only reduces the time to start debugging and remove the time involved in ongoing maintenance of test accounts, but may actually force out a few extra bugs that we wouldn&#039;t catch with a new, vanilla user account.&lt;/p&gt;

&lt;h3&gt;Support&lt;/h3&gt;
&lt;p&gt;Duplicating a bug or answering a question becomes a lot easier when we can emulate the person on the other end of the bug report or phone. We can emulate the person in our production environment and in our development environment and verify that both environments break in the same way (or that development doesn&#039;t break after we fix it). We also get firsthand clues, which can knock hours off the bug-hunting process.&lt;/p&gt;

&lt;h3&gt;Customer Service&lt;/h3&gt;
&lt;p&gt;Just as developers and support benefit on the technical side, in some cases Customer Service representatives (or selected members of the business) can use emulation to provide business or first level user support. When an end user has a complex question about an order or report, the service representative no longer needs to imagine their way through the issue, but instead can emulate that user, walk through the process, and see exactly what their user is seeing. This can be even more critical in systems where users see only a subset of the functionality or data available to service representatives.&lt;/p&gt;

&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;So emulation is a useful tool as well as a neat trick. Like many things, it is generally easier to bake this in from the beginning than to add it after the fact. If the user information is accessed in a consistent fashion in existing software, it is possible to squeeze in emulation logic and clean up the few places people cut corners and accessed users outside the normal context. If the user information is loaded and accessed at will throughout the application, adding emulation will be much harder (though there is some additional benefit in that it forces you to clean up your architecture a bit).&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Sample Session Context Class&lt;/b&gt;&lt;/p&gt;
&lt;div class=&quot;codebox&quot;&gt;&lt;div class=&quot;codeheader&quot;&gt;Code: &lt;span&gt;vbnet&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;codeholder&quot;&gt;&lt;div class=&quot;vbnet&quot; id=&quot;cb75035&quot; style=&quot;display: block; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Class&lt;/span&gt; SessionContext&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Private&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt; EmulatedUser &lt;span style=&quot;color: #0600FF;&quot;&gt;As&lt;/span&gt; User&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Private&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt; LoggedInUser &lt;span style=&quot;color: #0600FF;&quot;&gt;As&lt;/span&gt; User&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; ReadOnly &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt; User &lt;span style=&quot;color: #0600FF;&quot;&gt;As&lt;/span&gt; User&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; If &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;EmulatedUser&lt;/span&gt; IsNot &lt;span style=&quot;color: #0600FF;&quot;&gt;Nothing&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Then&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Return &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;EmulatedUser&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Else&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Return &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;LoggedInUser&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; If&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; ReadOnly &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt; IsEmulating &lt;span style=&quot;color: #0600FF;&quot;&gt;As&lt;/span&gt; Boolean&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Return &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;EmulatedUser&lt;/span&gt; IsNot &lt;span style=&quot;color: #0600FF;&quot;&gt;Nothing&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #008080; font-style: italic;&quot;&gt;&#039;&#039;&#039; &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #008080; font-style: italic;&quot;&gt;&#039;&#039;&#039; Property used for accessing current&#039;s users information for auditing&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #008080; font-style: italic;&quot;&gt;&#039;&#039;&#039; &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; ReadOnly &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt; UserIdForAuditing &lt;span style=&quot;color: #0600FF;&quot;&gt;As&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Integer&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; If &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;LoggedInUser&lt;/span&gt; IsNot &lt;span style=&quot;color: #0600FF;&quot;&gt;Nothing&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Then&lt;/span&gt; Return &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;LoggedInUser&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;UserID&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Return &lt;span style=&quot;color: #FF0000;&quot;&gt;0&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Get&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Property&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt; LogInUser&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0600FF;&quot;&gt;ByVal&lt;/span&gt; newUser &lt;span style=&quot;color: #0600FF;&quot;&gt;As&lt;/span&gt; User&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;LoggedInUser&lt;/span&gt; = newUser&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;EmulatedUser&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;Nothing&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #008080; font-style: italic;&quot;&gt;&#039; plus other login logic stuff&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt; LogOutUser&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;LoggedInUser&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;Nothing&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;EmulatedUser&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;Nothing&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt; StartEmulating&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0600FF;&quot;&gt;ByVal&lt;/span&gt; selectedUser &lt;span style=&quot;color: #0600FF;&quot;&gt;As&lt;/span&gt; User&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;EmulatedUser&lt;/span&gt; = selectedUser&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt; StopEmulating&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;Me&lt;/span&gt;.&lt;span style=&quot;color: #000000;&quot;&gt;EmulatedUser&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;Nothing&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #0600FF;&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;Class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id=&quot;cb53539&quot; style=&quot;display: none; color: red;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Altogether not that complex a code construct, although I&#039;m sure it will grow more so over the lifetime of the application. &lt;/p&gt;

&lt;p&gt;As long as we consistently access user information through the exposed User property in the session and user the exposed UserIdForAuditing property for auditing purposes, then most of the work is done for us. The only other piece we need is a button on the UI to start emulating and some logic to handle the danger below.&lt;/p&gt;

&lt;h2&gt;Dangers&lt;/h2&gt;
&lt;p&gt;There are two main dangers to watch for. The first danger is making sure emulation doesn&#039;t grant users the ability to promote themselves. Either emulation needs to be reserved for administrative users, or logic needs to be added to make certain levels or roles unavailable for emulation (or assignment during emulation).&lt;/p&gt;

&lt;p&gt;The other main danger is that you now have a much greater chance (probably guarantee) that you will have the same user &quot;logged in&quot; in two locations at once. Most applications handle this just fine, but there are also many that cannot. Examples of this behavior are enforcing single location sign-ons, coded security that assumes multiple location means an account has been compromised, and making the mistake of storing session data keyed only to a user id instead of a unique session.&lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/adding-user-emulation-to-an&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://lessthandot.com/&quot;&gt;LessThanDot&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>One of the tricks I picked up from my last job (and our forum software, now that I think of it) is the idea of user emulation. I could log into the application, search for a user, and, at the push of a button, temporarily become that user. The only differences between emulating them and actually logging in as them were a black bar that indicated who I am (with a link to stop emulating), all audit records continued to reflect my own user id, and I didn't need to keep track of 30 different sample accounts and passwords.</p>

<p>As I said, it's a neat trick. </p>

<h2>Advantages</h2>
<p>Implemented consistently, this stops being just a trick and becomes a very powerful tool. Developers, QA, even customer service and support see benefits from being able to quickly emulate end users.</p>

<h3>Debugging</h3>
<p>As developers the largest benefit for us is the ability to debug our systems from a variety of viewpoints. Rather than going through the trouble of creating and managing sample users for every impacted role, we can use existing user records with real data behind them. This not only reduces the time to start debugging and remove the time involved in ongoing maintenance of test accounts, but may actually force out a few extra bugs that we wouldn't catch with a new, vanilla user account.</p>

<h3>Support</h3>
<p>Duplicating a bug or answering a question becomes a lot easier when we can emulate the person on the other end of the bug report or phone. We can emulate the person in our production environment and in our development environment and verify that both environments break in the same way (or that development doesn't break after we fix it). We also get firsthand clues, which can knock hours off the bug-hunting process.</p>

<h3>Customer Service</h3>
<p>Just as developers and support benefit on the technical side, in some cases Customer Service representatives (or selected members of the business) can use emulation to provide business or first level user support. When an end user has a complex question about an order or report, the service representative no longer needs to imagine their way through the issue, but instead can emulate that user, walk through the process, and see exactly what their user is seeing. This can be even more critical in systems where users see only a subset of the functionality or data available to service representatives.</p>

<h2>Implementation</h2>
<p>So emulation is a useful tool as well as a neat trick. Like many things, it is generally easier to bake this in from the beginning than to add it after the fact. If the user information is accessed in a consistent fashion in existing software, it is possible to squeeze in emulation logic and clean up the few places people cut corners and accessed users outside the normal context. If the user information is loaded and accessed at will throughout the application, adding emulation will be much harder (though there is some additional benefit in that it forces you to clean up your architecture a bit).</p>

<p><b>Sample Session Context Class</b></p>
<div class="codebox"><div class="codeheader"><span>vbnet</span><div class="codebox_javascript_links"><a href="http://blogs.lessthandot.com" onclick="linenumberOnOff('cb14964'); return false;">Line number Off</a> | <a href="http://blogs.lessthandot.com#" onclick="expandCode('cb14964','cb78126'); return false;">Hide</a> | <a href="http://blogs.lessthandot.com#" onclick="selectCode(this); return false;">Select all</a></div></div><!-- we need this dummy div to fix a firefox bug when selecting code lines --><div class="codeholder"><div class="vbnet" id="cb14964" style="display: block; color: rgb(0, 0, 0);"><ol><li style="" class="li1"><span style="color: #0600FF;">Public</span> <span style="color: #0600FF;">Class</span> SessionContext</li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #0600FF;">Private</span> <span style="color: #0600FF;">Property</span> EmulatedUser <span style="color: #0600FF;">As</span> User</li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">Private</span> <span style="color: #0600FF;">Property</span> LoggedInUser <span style="color: #0600FF;">As</span> User</li><li style="" class="li1">&nbsp;</li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">Public</span> ReadOnly <span style="color: #0600FF;">Property</span> User <span style="color: #0600FF;">As</span> User</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Get</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">EmulatedUser</span> IsNot <span style="color: #0600FF;">Nothing</span> <span style="color: #0600FF;">Then</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Return <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">EmulatedUser</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Else</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Return <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">LoggedInUser</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">End</span> If</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Get</span></li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Property</span></li><li style="" class="li1">&nbsp;</li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">Public</span> ReadOnly <span style="color: #0600FF;">Property</span> IsEmulating <span style="color: #0600FF;">As</span> Boolean</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Get</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Return <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">EmulatedUser</span> IsNot <span style="color: #0600FF;">Nothing</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Get</span></li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Property</span></li><li style="" class="li1">&nbsp;</li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">''' &lt;summary&gt;</span></li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">''' Property used for accessing current's users information for auditing</span></li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #008080; font-style: italic;">''' &lt;/summary&gt;</span></li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #0600FF;">Public</span> ReadOnly <span style="color: #0600FF;">Property</span> UserIdForAuditing <span style="color: #0600FF;">As</span> <span style="color: #0600FF;">Integer</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Get</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; If <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">LoggedInUser</span> IsNot <span style="color: #0600FF;">Nothing</span> <span style="color: #0600FF;">Then</span> Return <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">LoggedInUser</span>.<span style="color: #000000;">UserID</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Return <span style="color: #FF0000;">0</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Get</span></li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Property</span></li><li style="" class="li1">&nbsp;</li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">Public</span> <span style="color: #0600FF;">Sub</span> LogInUser<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ByVal</span> newUser <span style="color: #0600FF;">As</span> User<span style="color: #000000;">&#41;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">LoggedInUser</span> = newUser</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">EmulatedUser</span> = <span style="color: #0600FF;">Nothing</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">' plus other login logic stuff</span></li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></li><li style="" class="li1">&nbsp;</li><li style="" class="li2">&nbsp; &nbsp; <span style="color: #0600FF;">Public</span> <span style="color: #0600FF;">Sub</span> LogOutUser<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">LoggedInUser</span> = <span style="color: #0600FF;">Nothing</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">EmulatedUser</span> = <span style="color: #0600FF;">Nothing</span></li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #0600FF;">Public</span> <span style="color: #0600FF;">Sub</span> StartEmulating<span style="color: #000000;">&#40;</span><span style="color: #0600FF;">ByVal</span> selectedUser <span style="color: #0600FF;">As</span> User<span style="color: #000000;">&#41;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">EmulatedUser</span> = selectedUser</li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #0600FF;">Public</span> <span style="color: #0600FF;">Sub</span> StopEmulating<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">Me</span>.<span style="color: #000000;">EmulatedUser</span> = <span style="color: #0600FF;">Nothing</span></li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Sub</span></li><li style="" class="li2"><span style="color: #0600FF;">End</span> <span style="color: #0600FF;">Class</span></li></ol></div><div id="cb78126" style="display: none; color: red;"></div></div></div>

<p>Altogether not that complex a code construct, although I'm sure it will grow more so over the lifetime of the application. </p>

<p>As long as we consistently access user information through the exposed User property in the session and user the exposed UserIdForAuditing property for auditing purposes, then most of the work is done for us. The only other piece we need is a button on the UI to start emulating and some logic to handle the danger below.</p>

<h2>Dangers</h2>
<p>There are two main dangers to watch for. The first danger is making sure emulation doesn't grant users the ability to promote themselves. Either emulation needs to be reserved for administrative users, or logic needs to be added to make certain levels or roles unavailable for emulation (or assignment during emulation).</p>

<p>The other main danger is that you now have a much greater chance (probably guarantee) that you will have the same user "logged in" in two locations at once. Most applications handle this just fine, but there are also many that cannot. Examples of this behavior are enforcing single location sign-ons, coded security that assumes multiple location means an account has been compromised, and making the mistake of storing session data keyed only to a user id instead of a unique session.</p><div class="item_footer"><p><small><a href="http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/adding-user-emulation-to-an">Original post</a> blogged on <a href="http://lessthandot.com/">LessThanDot</a>.</small></p></div>]]></content:encoded>
								<comments>http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/adding-user-emulation-to-an#comments</comments>
			<wfw:commentRss>http://blogs.lessthandot.com/index.php/Architect/?tempskin=_rss2&#38;disp=comments&#38;p=1206</wfw:commentRss>
		</item>
				<item>
			<title>Why (and How) I Model</title>
			<link>http://blogs.lessthandot.com/index.php/Architect/IntroductionArchitectureDesign/why-and-how-i-model</link>
			<pubDate>Fri, 15 Oct 2010 09:20:39 +0000</pubDate>			<dc:creator>Eli Weinstock-Herman (tarwn)</dc:creator>
			<category domain="main">Introduction to Architecture &amp; Design</category>			<guid isPermaLink="false">986@http://blogs.lessthandot.com/</guid>
						<description>&lt;p&gt;Over my years in (and before) IT, I&#039;ve seen long projects, failed projects, confused projects, wildly successful projects, and even fun projects that ended far differently than we expected. The consistent take-away for me is that I am a big picture type of person, and that understanding that big, abstract picture cuts out a lot of wasted time sprinting down the wrong paths.&lt;/p&gt;

&lt;div style=&quot;font-size: .8em; color: #666666; text-align: center;&quot;&gt;
&lt;img src=&quot;http://tiernok.com/LTDBlog/modeling/sprint.jpg&quot; alt=&quot;Don&#039;t Sprint Blindly&quot; /&gt;&lt;br /&gt;
Don&#039;t Sprint Blindly...&lt;br /&gt;(care of &lt;a href=&quot;http://www.dmitriev.com/blog/2009-04-14/wrong-sprint-burndown/&quot;&gt;dmitriev.com&lt;/a&gt;)
&lt;/div&gt;

&lt;p&gt;Creating a model forces me to refine a concept down to it&#039;s simplest elements, forces me to face the unknowns that my mind has so casually been skipping over. When done well, a model communicates a clear idea and replaces not only the thousands words required to explain it, but the 9000 I would have wasted getting there.&lt;/p&gt;

&lt;p&gt;I model to think through processes, question my assumptions, and provide guidance towards a solution. While it probably looks like something I threw together in about ten minutes, there are actually a lot of processes going on behind the scenes.&lt;/p&gt;

&lt;h2&gt;Purpose - What are We Drawing?&lt;/h2&gt;
&lt;div style=&quot;float: right; font-size: .8em; color: #666666; text-align: center;&quot;&gt;
&lt;img src=&quot;http://tiernok.com/LTDBlog/modeling/dostuff.jpg&quot; title=&quot;Do Stuff!&quot; /&gt;&lt;br /&gt;
No Goal? Here&#039;s a Diagram.
&lt;/div&gt;
&lt;p&gt;As with all things, a diagram should have a goal. A model that isn&#039;t trying to communicate an idea is filler for a report no one is going to read anyway. A goal should be concise and limited to a single subject or perspective:&lt;/p&gt;
&lt;ul style=&quot;margin-left: 1em;&quot;&gt;
  &lt;li&gt;The data flow from the end customer to our master data system&lt;/li&gt;
  &lt;li&gt;An order-to-cash business process&lt;/li&gt;
  &lt;li&gt;The functional architecture of a software application&lt;/li&gt;
  &lt;li&gt;A graphic representation of our current state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mess around with too many factors and at the end of the day a mess is all you&#039;ll  have:&lt;/p&gt;
&lt;ul style=&quot;margin-left: 1em;&quot;&gt;
  &lt;li&gt;The physical network topology combined with the disaster recovery plan and data flows between the systems&lt;/li&gt;
  &lt;li&gt;The application architecture with defined user work flows and user experience elements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or to translate: gobbledygook.&lt;/p&gt;

&lt;h2&gt;Constraint - Less is More&lt;/h2&gt;
&lt;p&gt;A goal provides me with my first constraint, and constraints are good. Defining constraints will keep my model simpler and consistent, which means the end message will be clearer. At the same time, a well-defined set of constraints will encourage creativity, providing a better end product.&lt;/p&gt;

&lt;p&gt;Often my constraints will include things like not allowing connections to cross, only using a very simple set of shapes, restricting myself to only a few shades of color, or setting time limits. I&#039;ll define the perspective I want to use with my goal, whether it will be a topological map, a flow, or just a set of connected shapes. &lt;/p&gt;

&lt;p&gt;This keeps me focused instead of playing with the entire palette of colors, shapes, and page sizes available in my favorite software tools.&lt;/p&gt;

&lt;h2&gt;Content - Work on a Temporary Surface&lt;/h2&gt;
&lt;p&gt;Even with constraints and a goal, I still don&#039;t know exactly where I will end up or what I will learn along the way, so I start on the whiteboard. With a whiteboard I can start diagramming out the pieces I know, add in new items or resolve question marks as I run into them, and easily combine and rearrange my thoughts. Some of my constraints will be ineffective at this stage, but natural constraints (like the number of markers I have and the board size) will replace them in helping my creativity and thought processes.&lt;/p&gt;

&lt;p&gt;This stage is also where I figure out my wording. Because it&#039;s so easy to see the big picture (heh) on my whiteboard, I also get a good feel for when words are too specific, not specific enough, or possibly just not quite the right word for what I am trying to communicate. Instead of focusing on getting all the boxes lined up, I can focus on using clear and consistent terminology that will help support the final model rather than detract from it.&lt;/p&gt;

&lt;h2&gt;Medium - Where is it Going?&lt;/h2&gt;
&lt;div style=&quot;float: left; font-size: .8em; color: #666666; text-align: center; margin: 2em 1em 1em 1em&quot;&gt;
&lt;img src=&quot;http://tiernok.com/trent/2004_11_05_04_sm.jpg&quot; title=&quot;Content needs context&quot; /&gt;&lt;br /&gt;
Content needs Context
&lt;/div&gt;
&lt;p&gt;As I make the transition from whiteboard to diagramming software, the last piece of the equation is to consider the medium I am going to use to communicate the model. A standalone diagram may put higher priority on further simplicity of shapes and colors, where a presentation model may put lower priority on text and higher priority on subtleties for deeper conversation. &lt;/p&gt;


&lt;p&gt;Will there need to be a legend? Is font-size 8 going to be a waste of time or readable font? If I use subtle shades of color will it all print the same color or show up in gloriously rendered imagery on a 12 foot display? Will adding a cartoon get a chuckle in a presentation or a frown in an executive review? Can I include a picture of my cat?&lt;/p&gt;

&lt;p&gt;The context the diagram will be communicating in will determine the last set of constraints.&lt;/p&gt;

&lt;h2&gt;Terminology - The Wrong Word Invalidates the Model&lt;/h2&gt;
&lt;div style=&quot;float: right; font-size: .8em; color: #666666; text-align: center;&quot;&gt;
&lt;img src=&quot;http://tiernok.com/LTDBlog/modeling/van-venn-diagram.jpg&quot; title=&quot;&#039;Van&#039; Diagram&quot; /&gt;&lt;br /&gt;
Using the right terminology, &lt;br /&gt;thanks &lt;a href=&quot;http://www.lolcaption.com/random-funny/what-is-a-van-diagram-you-ask-well-let-me-show-you/&quot;&gt;lolcaption.com&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;General wording may have been roughed in on the whiteboard and some really good words may have been chosen, but these now need to be examined in light of the future medium as well as the audience. In many cases, using a word out of context can distract my audience or even negate the model&#039;s message entirely.&lt;/p&gt;

&lt;p&gt;That being said, endless anxiety over perfection is nowhere near as good as a cool beer at the end of a work day, so we need to strike a balance between working through the night and achieving good enough. So I&#039;ll be careful, in general, when using customer terminology and try to be pragmatic in my search for the perfect name for the third box from the left.&lt;/p&gt;

&lt;h2&gt;Composition - Additional Layers of Meaning&lt;/h2&gt;
&lt;p&gt;The last stage of the model, having transferred it from whiteboard to software and applied corrections to terminology, is to add some depth that supports the initial concept. &lt;/p&gt;

&lt;p&gt;Colors, re-arranging layout to alter proximity, fonts, and even line thicknesses are all tools I use to add subtle depth to a model. If I am planning on presenting the model, I can start the discussion on the general message of the model and dive into these subtleties as the discussion progresses. A thicker line between two systems can communicate greater bandwidth or a more secure transport layer. A common shading of colors between multiple objects communicates a relationship or similarity. As with the stages before, I try to use constraint. Applying the whole palette and a different shape for each object may seem fun, but it&#039;s going to communicate confusion (and possibly a desire for medication).&lt;/p&gt;

&lt;p&gt;While working with the composition, I will also create temporary versions to play with drastically different layouts or shapes. This gives me a fresh look at a concept that has undoubtedly been on my whiteboard for days, giving me an opportunity to catch last minute holes or simply provide alternative layout options.&lt;/p&gt;

&lt;h2&gt;Sounds Like a Lot of Work...&lt;/h2&gt;
&lt;p&gt;There are different levels of work involved in modeling. In some cases even finding the time to stop doing and try to draw an idea may seem like a waste. &lt;/p&gt;
&lt;div style=&quot;float: right; font-size: .8em; color: #666666; text-align: center;&quot;&gt;
&lt;img src=&quot;http://tiernok.com/LTDBlog/modeling/lookbothways.jpg&quot; title=&quot;No Need To Look Ahead&quot; /&gt;&lt;br /&gt;
Not looking ahead?&lt;br /&gt;Diagram for that too...
&lt;/div&gt;
&lt;div style=&quot;font-size: .8em; margin: 1em;  padding: 1em;&quot;&gt;
&lt;p&gt;How do I judge when it is worth spending the time?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5 Minutes:&lt;/strong&gt; If it only takes five minutes to draw a fast diagram of what I am intending to do, then that 5 minutes didn&#039;t cost much and I can move forward with confidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30 Minutes:&lt;/strong&gt; If it takes 30 minutes, I&#039;ve erased and redrawn half of it, and the person I am explaining it to is still arguing with me, then it&#039;s time to draw a model. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 Hours:&lt;/strong&gt; If it takes 3 hours, we end with more questions than we started with, half the questions have the potential for refocusing the project, and we&#039;re still trying to figure out what to call this thing...yeah, it&#039;s definitely time to get a handle on what we&#039;re spending time on.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Jumping right into any project when we can&#039;t draw a high level summary means we&#039;re spending time and resources on something we can&#039;t adequately define. It doesn&#039;t matter how fast we&#039;re moving if we&#039;re spending that time running in random directions and ignoring cross-traffic.&lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://blogs.lessthandot.com/index.php/Architect/IntroductionArchitectureDesign/why-and-how-i-model&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://lessthandot.com/&quot;&gt;LessThanDot&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Over my years in (and before) IT, I've seen long projects, failed projects, confused projects, wildly successful projects, and even fun projects that ended far differently than we expected. The consistent take-away for me is that I am a big picture type of person, and that understanding that big, abstract picture cuts out a lot of wasted time sprinting down the wrong paths.</p>

<div style="font-size: .8em; color: #666666; text-align: center;">
<img src="http://tiernok.com/LTDBlog/modeling/sprint.jpg" alt="Don't Sprint Blindly" /><br />
Don't Sprint Blindly...<br />(care of <a href="http://www.dmitriev.com/blog/2009-04-14/wrong-sprint-burndown/">dmitriev.com</a>)
</div>

<p>Creating a model forces me to refine a concept down to it's simplest elements, forces me to face the unknowns that my mind has so casually been skipping over. When done well, a model communicates a clear idea and replaces not only the thousands words required to explain it, but the 9000 I would have wasted getting there.</p>

<p>I model to think through processes, question my assumptions, and provide guidance towards a solution. While it probably looks like something I threw together in about ten minutes, there are actually a lot of processes going on behind the scenes.</p>

<h2>Purpose - What are We Drawing?</h2>
<div style="float: right; font-size: .8em; color: #666666; text-align: center;">
<img src="http://tiernok.com/LTDBlog/modeling/dostuff.jpg" title="Do Stuff!" /><br />
No Goal? Here's a Diagram.
</div>
<p>As with all things, a diagram should have a goal. A model that isn't trying to communicate an idea is filler for a report no one is going to read anyway. A goal should be concise and limited to a single subject or perspective:</p>
<ul style="margin-left: 1em;">
  <li>The data flow from the end customer to our master data system</li>
  <li>An order-to-cash business process</li>
  <li>The functional architecture of a software application</li>
  <li>A graphic representation of our current state</li>
</ul>

<p>Mess around with too many factors and at the end of the day a mess is all you'll  have:</p>
<ul style="margin-left: 1em;">
  <li>The physical network topology combined with the disaster recovery plan and data flows between the systems</li>
  <li>The application architecture with defined user work flows and user experience elements</li>
</ul>

<p>Or to translate: gobbledygook.</p>

<h2>Constraint - Less is More</h2>
<p>A goal provides me with my first constraint, and constraints are good. Defining constraints will keep my model simpler and consistent, which means the end message will be clearer. At the same time, a well-defined set of constraints will encourage creativity, providing a better end product.</p>

<p>Often my constraints will include things like not allowing connections to cross, only using a very simple set of shapes, restricting myself to only a few shades of color, or setting time limits. I'll define the perspective I want to use with my goal, whether it will be a topological map, a flow, or just a set of connected shapes. </p>

<p>This keeps me focused instead of playing with the entire palette of colors, shapes, and page sizes available in my favorite software tools.</p>

<h2>Content - Work on a Temporary Surface</h2>
<p>Even with constraints and a goal, I still don't know exactly where I will end up or what I will learn along the way, so I start on the whiteboard. With a whiteboard I can start diagramming out the pieces I know, add in new items or resolve question marks as I run into them, and easily combine and rearrange my thoughts. Some of my constraints will be ineffective at this stage, but natural constraints (like the number of markers I have and the board size) will replace them in helping my creativity and thought processes.</p>

<p>This stage is also where I figure out my wording. Because it's so easy to see the big picture (heh) on my whiteboard, I also get a good feel for when words are too specific, not specific enough, or possibly just not quite the right word for what I am trying to communicate. Instead of focusing on getting all the boxes lined up, I can focus on using clear and consistent terminology that will help support the final model rather than detract from it.</p>

<h2>Medium - Where is it Going?</h2>
<div style="float: left; font-size: .8em; color: #666666; text-align: center; margin: 2em 1em 1em 1em">
<img src="http://tiernok.com/trent/2004_11_05_04_sm.jpg" title="Content needs context" /><br />
Content needs Context
</div>
<p>As I make the transition from whiteboard to diagramming software, the last piece of the equation is to consider the medium I am going to use to communicate the model. A standalone diagram may put higher priority on further simplicity of shapes and colors, where a presentation model may put lower priority on text and higher priority on subtleties for deeper conversation. </p>


<p>Will there need to be a legend? Is font-size 8 going to be a waste of time or readable font? If I use subtle shades of color will it all print the same color or show up in gloriously rendered imagery on a 12 foot display? Will adding a cartoon get a chuckle in a presentation or a frown in an executive review? Can I include a picture of my cat?</p>

<p>The context the diagram will be communicating in will determine the last set of constraints.</p>

<h2>Terminology - The Wrong Word Invalidates the Model</h2>
<div style="float: right; font-size: .8em; color: #666666; text-align: center;">
<img src="http://tiernok.com/LTDBlog/modeling/van-venn-diagram.jpg" title="'Van' Diagram" /><br />
Using the right terminology, <br />thanks <a href="http://www.lolcaption.com/random-funny/what-is-a-van-diagram-you-ask-well-let-me-show-you/">lolcaption.com</a>
</div>
<p>General wording may have been roughed in on the whiteboard and some really good words may have been chosen, but these now need to be examined in light of the future medium as well as the audience. In many cases, using a word out of context can distract my audience or even negate the model's message entirely.</p>

<p>That being said, endless anxiety over perfection is nowhere near as good as a cool beer at the end of a work day, so we need to strike a balance between working through the night and achieving good enough. So I'll be careful, in general, when using customer terminology and try to be pragmatic in my search for the perfect name for the third box from the left.</p>

<h2>Composition - Additional Layers of Meaning</h2>
<p>The last stage of the model, having transferred it from whiteboard to software and applied corrections to terminology, is to add some depth that supports the initial concept. </p>

<p>Colors, re-arranging layout to alter proximity, fonts, and even line thicknesses are all tools I use to add subtle depth to a model. If I am planning on presenting the model, I can start the discussion on the general message of the model and dive into these subtleties as the discussion progresses. A thicker line between two systems can communicate greater bandwidth or a more secure transport layer. A common shading of colors between multiple objects communicates a relationship or similarity. As with the stages before, I try to use constraint. Applying the whole palette and a different shape for each object may seem fun, but it's going to communicate confusion (and possibly a desire for medication).</p>

<p>While working with the composition, I will also create temporary versions to play with drastically different layouts or shapes. This gives me a fresh look at a concept that has undoubtedly been on my whiteboard for days, giving me an opportunity to catch last minute holes or simply provide alternative layout options.</p>

<h2>Sounds Like a Lot of Work...</h2>
<p>There are different levels of work involved in modeling. In some cases even finding the time to stop doing and try to draw an idea may seem like a waste. </p>
<div style="float: right; font-size: .8em; color: #666666; text-align: center;">
<img src="http://tiernok.com/LTDBlog/modeling/lookbothways.jpg" title="No Need To Look Ahead" /><br />
Not looking ahead?<br />Diagram for that too...
</div>
<div style="font-size: .8em; margin: 1em;  padding: 1em;">
<p>How do I judge when it is worth spending the time?</p>

<p><strong>5 Minutes:</strong> If it only takes five minutes to draw a fast diagram of what I am intending to do, then that 5 minutes didn't cost much and I can move forward with confidence.</p>

<p><strong>30 Minutes:</strong> If it takes 30 minutes, I've erased and redrawn half of it, and the person I am explaining it to is still arguing with me, then it's time to draw a model. </p>

<p><strong>3 Hours:</strong> If it takes 3 hours, we end with more questions than we started with, half the questions have the potential for refocusing the project, and we're still trying to figure out what to call this thing...yeah, it's definitely time to get a handle on what we're spending time on.</p>
</div>

<p>Jumping right into any project when we can't draw a high level summary means we're spending time and resources on something we can't adequately define. It doesn't matter how fast we're moving if we're spending that time running in random directions and ignoring cross-traffic.</p><div class="item_footer"><p><small><a href="http://blogs.lessthandot.com/index.php/Architect/IntroductionArchitectureDesign/why-and-how-i-model">Original post</a> blogged on <a href="http://lessthandot.com/">LessThanDot</a>.</small></p></div>]]></content:encoded>
								<comments>http://blogs.lessthandot.com/index.php/Architect/IntroductionArchitectureDesign/why-and-how-i-model#comments</comments>
			<wfw:commentRss>http://blogs.lessthandot.com/index.php/Architect/?tempskin=_rss2&#38;disp=comments&#38;p=986</wfw:commentRss>
		</item>
				<item>
			<title>Model-View-Presenter: Looking at Passive View</title>
			<link>http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/model-view-presenter-looking-at-passive</link>
			<pubDate>Thu, 15 Jul 2010 09:44:12 +0000</pubDate>			<dc:creator>Eli Weinstock-Herman (tarwn)</dc:creator>
			<category domain="main">Designing Software</category>
<category domain="alt">Introduction to Architecture &amp; Design</category>			<guid isPermaLink="false">889@http://blogs.lessthandot.com/</guid>
						<description>&lt;p&gt;Model-View-Presenter is an architecture pattern that defines a structure for behavior and logic at the UI level. M-V-P separates the logic of the presentation, such as interacting with back-end services and the business layer, from the mechanics of displaying buttons and interface components. &lt;/p&gt;

&lt;p&gt;I often build small projects to help understand and grow my skills as a developer, architect, and all-around technologist (as may be apparent from the &lt;a href=&quot;http://blogs.lessthandot.com/index.php/All/?disp=authdir&amp;amp;author=9&quot; target=&quot;_blank&quot; title=&quot;See all of my posts at LTD&quot;&gt;wide range of topics I post on&lt;/a&gt;). Today I worked with a combination of Visio and Visual Studio to build a sample project to play with the Passive View concept and to help grow my own understanding of the concept. This post will cover the Visio side of my learning-curve.&lt;/p&gt;

&lt;p&gt;You can read more about Model View Presenter at &lt;a href=&quot;http://en.wikipedia.org/wiki/Model-view-presenter&quot; target=&quot;_blank&quot; title=&quot;Model-View-Presenter at Wikipedia&quot;&gt;Wikipedia&lt;/a&gt; and &lt;a href=http://msdn.microsoft.com/en-us/magazine/cc188690.aspx&quot;&quot; target=&quot;_blank&quot; title=&quot;Model View Presenter by Jean-Paul Boodhoo on MSDN&quot;&gt;MSDN&lt;/a&gt;. Perhaps the best information can be found on Martin Fowler&#039;s site, where he has separate write-ups on &lt;a href=&quot;http://www.martinfowler.com/eaaDev/PassiveScreen.html&quot; target=_blank&quot; title=&quot;Passive View pattern&quot;&gt;Passive View&lt;/a&gt; and &lt;a href=&quot;http://www.martinfowler.com/eaaDev/SupervisingPresenter.html&quot; target=_blank&quot; title=&quot;Supervising Controller Pattern&quot;&gt;Supervising Controller&lt;/a&gt;.&lt;/p&gt;

&lt;div style=&quot;background-color:#FFFFCC; padding: .5em; margin: .5em; border: 1px solid #DDDDAA; color: #333333; font-size: 80%;&quot;&gt;Note: I know some people were waiting for another Virtual Lab entry this week, and here I am writing about Architecture instead. Don&#039;t worry, the virtual lab series will continue, I just felt like doing a write-up while I was playing this past weekend.&lt;/div&gt;

&lt;h2&gt;Passive View&lt;/h2&gt;
&lt;p&gt;Passive View is a subset of the Model-View-Presenter pattern. In Passive View, the interface is responsible for handling interface-specific logic, such as figuring out how to put a value in a textbox or react to events from button clicks, but all actions and logic outside of the raw UI are sent to the Presenter to execute or manage. The Presenter is responsible for calling business methods in the Business model and updating the data that is available in the View. &lt;/p&gt;

&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666;&quot;&gt;
&lt;img src=&quot;http://tiernok.com/LTDBlog/MVP/mvp.png&quot; alt=&quot;Basic Model-View-Presenter diagram&quot; /&gt;&lt;br /&gt;
Basic Model-View-Presenter Diagram
&lt;/div&gt;

&lt;p&gt;From the outside in, the architecture for Passive View looks something like this:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;UI - The User Interface reflects what is going on beneath it by implementing one or more View interfaces&lt;/li&gt;
	&lt;li&gt;Presenter - The Presenter receives interactions from the UI or Model and updates the Views it is attached to&lt;/li&gt;
	&lt;li&gt;Model - The model is a facade or black box in our diagram, behind which is a business logic layer and data layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a flat architecture we would collect data from the interface, perhaps do some business and data validation, and then save it directly to a database using stored procedures or inline SQL. Defining a data access layer (or data model like entity framework) allows our application to operate on cohesive, defined objects that are meaningful to the application and stored and retrieved consistently. Defining a business logic layer allows us to centralize business rules that operate on entities in our application in a manner that is consistent with the business and internally consistent in the application, minimizing the risk that occurs when making changes to the business flow. Separating the logic of populating inputs and responding to button presses on the UI from the information being communicated to the end user and conceptual responses to their input allows the system to interact with the user consistently across any number of interfaces into the same application.&lt;/p&gt;

&lt;p&gt;The definition of each level increases our ability to automate testing and supports greater &lt;a href=&quot;http://en.wikipedia.org/wiki/Separation_of_concerns&quot; title=&quot;Separation of Concerns at Wikipedia&quot; target=&quot;_blank&quot;&gt;Separation of Concerns&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Implementing a Sample Project&lt;/h2&gt;
&lt;p&gt;My learning exercise has been the the creation of an ASP.Net search page that allows an end user (customer) to search for finished products from the AdventureWorks sample database. The architecture and design decisions were done as an exercise in Visio using simple shapes and layouts.&lt;/p&gt;

&lt;p&gt;My example application has several functional and non-functional requirements:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Functional - Display product number, name, list price, and available quantity in tabular format&lt;/li&gt;
	&lt;li&gt;Functional - Provide a basic search input and button to search product names&lt;/li&gt;
	&lt;li&gt;Non-Functional - Implement an M-V-P pattern - Obviously the purpose of this whole exercise&lt;/li&gt;
	&lt;li&gt;Non-Functional - Use a simple model stack that can be easily replaced with a Service-Oriented one at a later time&lt;/li&gt;
	&lt;li&gt;Non-Functional - Build with the idea that we will later create a Silverlight or WPF front-end&lt;/li&gt;
	&lt;li&gt;Non-Functional - Make pretty pictures for article&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;i&gt;My unwritten, final requirement was to finish the whole thing in half a day, though luckily I didn&#039;t define whether I intended that to mean 4 hours or 12.&lt;/i&gt;&lt;/p&gt;

&lt;h3&gt;Initial Architecture&lt;/h3&gt;
&lt;p&gt;To start I created a diagram of the application architecture:&lt;/p&gt;
&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666;&quot;&gt;
&lt;img src=&quot;http://tiernok.com/LTDBlog/MVP/mvp_arch_01.png&quot; alt=&quot;More extensive M-V-P Diagram&quot; /&gt;&lt;br /&gt;
More Extensive Model-View-Presenter Diagram
&lt;/div&gt;
&lt;p&gt;The purple layer is my presentation layer, which reflects the View. The blue layer is my Presenter layer which contains the logic for interacting between the end user and interface as well as a definition, or contract, of the information available in the View. The Green is the Model (or is behind the model, depending on your viewpoint) and exposes business functions and data entities for the Presenter to interact with.&lt;/p&gt;

&lt;h3&gt;Class Layout&lt;/h3&gt;
&lt;p&gt;Once the high level diagram was completed, I could approach the task of creating some base classes and interfaces to use in implementing the project.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Model.IModel - Generic Model Interface to expose business calls to Presenters&lt;/li&gt;
	&lt;li&gt;Presenter.IView - Generic View Interface that all Presenters can interact with and all screens implement&lt;/li&gt;
	&lt;li&gt;Presenter.BasePresenter - Generic Presenter class that all Presenters will implement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To keep the project to a single morning but also allow the ability to come back and build a more architecturally sound solution, I implemented the Model in a very basic fashion that was referenced locally by the Presenter project and makes direct calls to SQL Server using ADO and parametrized, inline SQL. This buys me the benefits of having a well-defined Model (via the interface) but allows me concentrate my time and effort on the learning part of the project (ie, the M-V-P interaction and structure). Defining the model interface also leaves me open to come back and replace it with better separated code and the ability to create a model that acts as a facade to a service stack, instead of local DLLs.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Model.BasicModel.Model - Basic implementation of a model that will interact with AdventureWorks on SQL Server&lt;/li&gt;
	&lt;li&gt;Model.Entities.Product - A Product Entity that can be communicated between an IModel instance and Presenter&lt;br /&gt;
	&lt;li&gt;Presenter.ProductSearchPresenter - A Presenter to manage product search interface&lt;/li&gt;
	&lt;li&gt;Presenter.IProductSearchView - A view of the data involved in a product search&lt;/li&gt;
	&lt;li&gt;ProductSearch.aspx - A web page that implements the IProductSearchView and interacts with the ProductSearchPresenter&lt;/li&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;My final Visio diagram ended up looking like this:&lt;/p&gt;
&lt;div style=&quot;text-align: center; font-size: .8em; color: #666666;&quot;&gt;
&lt;img src=&quot;http://tiernok.com/LTDBlog/MVP/mvp_arch_02.png&quot; alt=&quot;Example Application Diagram&quot; /&gt;&lt;br /&gt;
Diagram of Example Application
&lt;/div&gt;

&lt;p&gt;In this case the left side represents basic components (bases classes and interfaces) that are used to define common structure or contracts on the right side. &lt;/p&gt;

&lt;h2&gt;The Code&lt;/h2&gt;
&lt;p&gt;For the purposes of the example project, my view has properties for Search Text, a Search Count (number of results), Results (a generic list of the Product entity), and a boolean indicating whether there are results to display. My Web Form implements these properties, tying them to elements on the screen.&lt;/p&gt;

&lt;div class=&quot;codebox&quot;&gt;&lt;div class=&quot;codeheader&quot;&gt;Code: &lt;span&gt;csharp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;codeholder&quot;&gt;&lt;div class=&quot;csharp&quot; id=&quot;cb45401&quot; style=&quot;display: block; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: #0600FF;&quot;&gt;public&lt;/span&gt; partial &lt;span style=&quot;color: #FF0000;&quot;&gt;class&lt;/span&gt; WebForm1 : &lt;span style=&quot;color: #000000;&quot;&gt;System&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;Web&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;UI&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;Page&lt;/span&gt;, Presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;Views&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;IProductSearchView&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;ProductSearchPresenter&lt;/span&gt; _presenter;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;void&lt;/span&gt; Page_Load&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;object&lt;/span&gt; sender, EventArgs e&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; btnSearch.&lt;span style=&quot;color: #0000FF;&quot;&gt;Click&lt;/span&gt; += &lt;a href=&quot;http://www.google.com/search?q=new+msdn.microsoft.com&quot;&gt;&lt;span style=&quot;color: #008000;&quot;&gt;new&lt;/span&gt;&lt;/a&gt; EventHandler&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;btnSearch_Click&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rptProducts.&lt;span style=&quot;color: #0000FF;&quot;&gt;ItemDataBound&lt;/span&gt; += &lt;a href=&quot;http://www.google.com/search?q=new+msdn.microsoft.com&quot;&gt;&lt;span style=&quot;color: #008000;&quot;&gt;new&lt;/span&gt;&lt;/a&gt; RepeaterItemEventHandler&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;rptProducts_ItemDataBound&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _presenter = &lt;a href=&quot;http://www.google.com/search?q=new+msdn.microsoft.com&quot;&gt;&lt;span style=&quot;color: #008000;&quot;&gt;new&lt;/span&gt;&lt;/a&gt; Presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;ProductSearchPresenter&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.google.com/search?q=new+msdn.microsoft.com&quot;&gt;&lt;span style=&quot;color: #008000;&quot;&gt;new&lt;/span&gt;&lt;/a&gt; Model.&lt;span style=&quot;color: #0000FF;&quot;&gt;LocalModel&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;BasicModel&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;System&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;Configuration&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;ConfigurationManager&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;ConnectionStrings&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #808080;&quot;&gt;&amp;quot;AdventureWorks&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;ConnectionString&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;void&lt;/span&gt; btnSearch_Click&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #FF0000;&quot;&gt;object&lt;/span&gt; sender, EventArgs e&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;ExecuteProductSearch&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #FF0000;&quot;&gt;string&lt;/span&gt; Presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;Views&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;IProductSearchView&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;SearchText&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; get &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;return&lt;/span&gt; tbSearch.&lt;span style=&quot;color: #0000FF;&quot;&gt;Text&lt;/span&gt;; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt; tbSearch.&lt;span style=&quot;color: #0000FF;&quot;&gt;Text&lt;/span&gt; = value; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #FF0000;&quot;&gt;int&lt;/span&gt; Presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;Views&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;IProductSearchView&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;ResultCount&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt; lblResultCount.&lt;span style=&quot;color: #0000FF;&quot;&gt;Text&lt;/span&gt; = value.&lt;span style=&quot;color: #0000FF;&quot;&gt;ToString&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;Model.&lt;span style=&quot;color: #0000FF;&quot;&gt;Entities&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;Product&lt;/span&gt;&amp;gt; Presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;Views&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;IProductSearchView&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;SearchResults&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;value != &lt;span style=&quot;color: #0600FF;&quot;&gt;null&lt;/span&gt; &amp;amp;&amp;amp; value.&lt;span style=&quot;color: #0000FF;&quot;&gt;Count&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rptProducts.&lt;span style=&quot;color: #0000FF;&quot;&gt;DataSource&lt;/span&gt; = value;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rptProducts.&lt;span style=&quot;color: #0000FF;&quot;&gt;DataBind&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #FF0000;&quot;&gt;bool&lt;/span&gt; Presenter.&lt;span style=&quot;color: #0000FF;&quot;&gt;Views&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;IProductSearchView&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;DisplayResults&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; set &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt; tblResults.&lt;span style=&quot;color: #0000FF;&quot;&gt;Visible&lt;/span&gt; = value; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id=&quot;cb7455&quot; style=&quot;display: none; color: red;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As the presenter populates properties in the view, the information is automatically reflected on the page. The actual logic of how the business functions are called and populate those properties are neatly packaged up in the Presenter and View interface and very little logic occurs in the actual web form.&lt;/p&gt;

&lt;div class=&quot;codebox&quot;&gt;&lt;div class=&quot;codeheader&quot;&gt;Code: &lt;span&gt;csharp&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;codeholder&quot;&gt;&lt;div class=&quot;csharp&quot; id=&quot;cb55251&quot; style=&quot;display: block; color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;color: #0600FF;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;class&lt;/span&gt; ProductSearchPresenter : BasePresenter &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;protected&lt;/span&gt; Views.&lt;span style=&quot;color: #0000FF;&quot;&gt;IProductSearchView&lt;/span&gt; _view;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;public&lt;/span&gt; ProductSearchPresenter&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;Model.&lt;span style=&quot;color: #0000FF;&quot;&gt;IModel&lt;/span&gt; model, Views.&lt;span style=&quot;color: #0000FF;&quot;&gt;IProductSearchView&lt;/span&gt; view&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt; : &lt;span style=&quot;color: #0600FF;&quot;&gt;base&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;model&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view = view;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;ResultCount&lt;/span&gt; = &lt;span style=&quot;color: #FF0000;&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;DisplayResults&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0600FF;&quot;&gt;void&lt;/span&gt; ExecuteProductSearch&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;Model.&lt;span style=&quot;color: #0000FF;&quot;&gt;Entities&lt;/span&gt;.&lt;span style=&quot;color: #0000FF;&quot;&gt;Product&lt;/span&gt;&amp;gt; results;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; results = &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._model.&lt;span style=&quot;color: #0000FF;&quot;&gt;SearchProduct&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;SearchText&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#40;&lt;/span&gt;results.&lt;span style=&quot;color: #0000FF;&quot;&gt;Count&lt;/span&gt; &amp;gt; &lt;span style=&quot;color: #FF0000;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;ResultCount&lt;/span&gt; = results.&lt;span style=&quot;color: #0000FF;&quot;&gt;Count&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;DisplayResults&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;true&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;SearchResults&lt;/span&gt; = results;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;ResultCount&lt;/span&gt; = &lt;span style=&quot;color: #FF0000;&quot;&gt;0&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;DisplayResults&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF;&quot;&gt;this&lt;/span&gt;._view.&lt;span style=&quot;color: #0000FF;&quot;&gt;SearchResults&lt;/span&gt; = &lt;span style=&quot;color: #0600FF;&quot;&gt;null&lt;/span&gt;;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id=&quot;cb24899&quot; style=&quot;display: none; color: red;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To create a unit test, we define a simple view that implements the view interface, execute the presenter logic, and verify the properties are populated the way we would expect when the same presenter calls are made from the interface.&lt;/p&gt;

&lt;h3&gt;Extending the Architecture Further&lt;/h3&gt;
&lt;p&gt;Extending the application to display product search in a different manner would only require the addition of a new interface that also implements the Product Search View. A Silverlight front-end would only require creating the basic project, implementing the product search View, and wiring the new interface controls to the view properties. To replace the direct mode reference with a service reference, we could create a service facade that implemented the IModel interface, connected to a local or remote WCF service behid the scenes to handle the real model logic. And finally, instead of counting on our QA department to test all of the application interactions, we can create unit tests directly against the Presenter and Views to ensure that all of the interactions below the top surface of the application are happening consistently and to our expectation.&lt;/p&gt;

&lt;h2&gt;Your Turn&lt;/h2&gt;
&lt;p&gt;Getting this much of the architecture working is a good first step. I took a number of shortcuts on the BasicModel class in my example, but I now have a functional Model-View-Presenter application to play with. Hopefully there was enough information in the article to interest you in trying this out on your own. I urge you to read the articles linked in the top of the post (or several more in my &lt;a href=&quot;http://delicious.com/tarwn/model-view-presenter&quot; title=&quot;Eli&#039;s Delicious bookmarks for M-V-P&quot; target=&quot;_blank&quot;&gt;Model-View-Presentation bookmarks&lt;/a&gt;) and come up with your own diagrams and sample project. Even doing a small project will force you to run into questions and considerations you wouldn&#039;t have had by simply reading about it, not to mention unrelated tidbits you will pick up along the way (for instance, I also learned about &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms668604.aspx&quot; title=&quot;ObservableCollection at MSDN&quot; target=&quot;_blank&quot;&gt;ObservableCollections&lt;/a&gt; today).&lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/model-view-presenter-looking-at-passive&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://lessthandot.com/&quot;&gt;LessThanDot&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Model-View-Presenter is an architecture pattern that defines a structure for behavior and logic at the UI level. M-V-P separates the logic of the presentation, such as interacting with back-end services and the business layer, from the mechanics of displaying buttons and interface components. </p>

<p>I often build small projects to help understand and grow my skills as a developer, architect, and all-around technologist (as may be apparent from the <a href="http://blogs.lessthandot.com/index.php/All/?disp=authdir&amp;author=9" target="_blank" title="See all of my posts at LTD">wide range of topics I post on</a>). Today I worked with a combination of Visio and Visual Studio to build a sample project to play with the Passive View concept and to help grow my own understanding of the concept. This post will cover the Visio side of my learning-curve.</p>

<p>You can read more about Model View Presenter at <a href="http://en.wikipedia.org/wiki/Model-view-presenter" target="_blank" title="Model-View-Presenter at Wikipedia">Wikipedia</a> and <a href=http://msdn.microsoft.com/en-us/magazine/cc188690.aspx"" target="_blank" title="Model View Presenter by Jean-Paul Boodhoo on MSDN">MSDN</a>. Perhaps the best information can be found on Martin Fowler's site, where he has separate write-ups on <a href="http://www.martinfowler.com/eaaDev/PassiveScreen.html" target=_blank" title="Passive View pattern">Passive View</a> and <a href="http://www.martinfowler.com/eaaDev/SupervisingPresenter.html" target=_blank" title="Supervising Controller Pattern">Supervising Controller</a>.</p>

<div style="background-color:#FFFFCC; padding: .5em; margin: .5em; border: 1px solid #DDDDAA; color: #333333; font-size: 80%;">Note: I know some people were waiting for another Virtual Lab entry this week, and here I am writing about Architecture instead. Don't worry, the virtual lab series will continue, I just felt like doing a write-up while I was playing this past weekend.</div>

<h2>Passive View</h2>
<p>Passive View is a subset of the Model-View-Presenter pattern. In Passive View, the interface is responsible for handling interface-specific logic, such as figuring out how to put a value in a textbox or react to events from button clicks, but all actions and logic outside of the raw UI are sent to the Presenter to execute or manage. The Presenter is responsible for calling business methods in the Business model and updating the data that is available in the View. </p>

<div style="text-align: center; font-size: .8em; color: #666666;">
<img src="http://tiernok.com/LTDBlog/MVP/mvp.png" alt="Basic Model-View-Presenter diagram" /><br />
Basic Model-View-Presenter Diagram
</div>

<p>From the outside in, the architecture for Passive View looks something like this:</p>
<ul>
	<li>UI - The User Interface reflects what is going on beneath it by implementing one or more View interfaces</li>
	<li>Presenter - The Presenter receives interactions from the UI or Model and updates the Views it is attached to</li>
	<li>Model - The model is a facade or black box in our diagram, behind which is a business logic layer and data layer</li>
</ul>

<p>In a flat architecture we would collect data from the interface, perhaps do some business and data validation, and then save it directly to a database using stored procedures or inline SQL. Defining a data access layer (or data model like entity framework) allows our application to operate on cohesive, defined objects that are meaningful to the application and stored and retrieved consistently. Defining a business logic layer allows us to centralize business rules that operate on entities in our application in a manner that is consistent with the business and internally consistent in the application, minimizing the risk that occurs when making changes to the business flow. Separating the logic of populating inputs and responding to button presses on the UI from the information being communicated to the end user and conceptual responses to their input allows the system to interact with the user consistently across any number of interfaces into the same application.</p>

<p>The definition of each level increases our ability to automate testing and supports greater <a href="http://en.wikipedia.org/wiki/Separation_of_concerns" title="Separation of Concerns at Wikipedia" target="_blank">Separation of Concerns</a>.</p>

<h2>Implementing a Sample Project</h2>
<p>My learning exercise has been the the creation of an ASP.Net search page that allows an end user (customer) to search for finished products from the AdventureWorks sample database. The architecture and design decisions were done as an exercise in Visio using simple shapes and layouts.</p>

<p>My example application has several functional and non-functional requirements:</p>
<ol>
	<li>Functional - Display product number, name, list price, and available quantity in tabular format</li>
	<li>Functional - Provide a basic search input and button to search product names</li>
	<li>Non-Functional - Implement an M-V-P pattern - Obviously the purpose of this whole exercise</li>
	<li>Non-Functional - Use a simple model stack that can be easily replaced with a Service-Oriented one at a later time</li>
	<li>Non-Functional - Build with the idea that we will later create a Silverlight or WPF front-end</li>
	<li>Non-Functional - Make pretty pictures for article</li>
</ol>

<p><i>My unwritten, final requirement was to finish the whole thing in half a day, though luckily I didn't define whether I intended that to mean 4 hours or 12.</i></p>

<h3>Initial Architecture</h3>
<p>To start I created a diagram of the application architecture:</p>
<div style="text-align: center; font-size: .8em; color: #666666;">
<img src="http://tiernok.com/LTDBlog/MVP/mvp_arch_01.png" alt="More extensive M-V-P Diagram" /><br />
More Extensive Model-View-Presenter Diagram
</div>
<p>The purple layer is my presentation layer, which reflects the View. The blue layer is my Presenter layer which contains the logic for interacting between the end user and interface as well as a definition, or contract, of the information available in the View. The Green is the Model (or is behind the model, depending on your viewpoint) and exposes business functions and data entities for the Presenter to interact with.</p>

<h3>Class Layout</h3>
<p>Once the high level diagram was completed, I could approach the task of creating some base classes and interfaces to use in implementing the project.</p>
<ul>
	<li>Model.IModel - Generic Model Interface to expose business calls to Presenters</li>
	<li>Presenter.IView - Generic View Interface that all Presenters can interact with and all screens implement</li>
	<li>Presenter.BasePresenter - Generic Presenter class that all Presenters will implement</li>
</ul>

<p>To keep the project to a single morning but also allow the ability to come back and build a more architecturally sound solution, I implemented the Model in a very basic fashion that was referenced locally by the Presenter project and makes direct calls to SQL Server using ADO and parametrized, inline SQL. This buys me the benefits of having a well-defined Model (via the interface) but allows me concentrate my time and effort on the learning part of the project (ie, the M-V-P interaction and structure). Defining the model interface also leaves me open to come back and replace it with better separated code and the ability to create a model that acts as a facade to a service stack, instead of local DLLs.</p>
<ul>
	<li>Model.BasicModel.Model - Basic implementation of a model that will interact with AdventureWorks on SQL Server</li>
	<li>Model.Entities.Product - A Product Entity that can be communicated between an IModel instance and Presenter<br />
	<li>Presenter.ProductSearchPresenter - A Presenter to manage product search interface</li>
	<li>Presenter.IProductSearchView - A view of the data involved in a product search</li>
	<li>ProductSearch.aspx - A web page that implements the IProductSearchView and interacts with the ProductSearchPresenter</li>
</li></ul>

<p>My final Visio diagram ended up looking like this:</p>
<div style="text-align: center; font-size: .8em; color: #666666;">
<img src="http://tiernok.com/LTDBlog/MVP/mvp_arch_02.png" alt="Example Application Diagram" /><br />
Diagram of Example Application
</div>

<p>In this case the left side represents basic components (bases classes and interfaces) that are used to define common structure or contracts on the right side. </p>

<h2>The Code</h2>
<p>For the purposes of the example project, my view has properties for Search Text, a Search Count (number of results), Results (a generic list of the Product entity), and a boolean indicating whether there are results to display. My Web Form implements these properties, tying them to elements on the screen.</p>

<div class="codebox"><div class="codeheader"><span>csharp</span><div class="codebox_javascript_links"><a href="http://blogs.lessthandot.com" onclick="linenumberOnOff('cb11582'); return false;">Line number Off</a> | <a href="http://blogs.lessthandot.com#" onclick="expandCode('cb11582','cb47541'); return false;">Hide</a> | <a href="http://blogs.lessthandot.com#" onclick="selectCode(this); return false;">Select all</a></div></div><!-- we need this dummy div to fix a firefox bug when selecting code lines --><div class="codeholder"><div class="csharp" id="cb11582" style="display: block; color: rgb(0, 0, 0);"><ol><li style="" class="li1"><span style="color: #0600FF;">public</span> partial <span style="color: #FF0000;">class</span> WebForm1 : <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">UI</span>.<span style="color: #0000FF;">Page</span>, Presenter.<span style="color: #0000FF;">Views</span>.<span style="color: #0000FF;">IProductSearchView</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; Presenter.<span style="color: #0000FF;">ProductSearchPresenter</span> _presenter;</li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">void</span> Page_Load<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; btnSearch.<span style="color: #0000FF;">Click</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> EventHandler<span style="color: #000000;">&#40;</span>btnSearch_Click<span style="color: #000000;">&#41;</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rptProducts.<span style="color: #0000FF;">ItemDataBound</span> += <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> RepeaterItemEventHandler<span style="color: #000000;">&#40;</span>rptProducts_ItemDataBound<span style="color: #000000;">&#41;</span>;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _presenter = <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Presenter.<span style="color: #0000FF;">ProductSearchPresenter</span><span style="color: #000000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Model.<span style="color: #0000FF;">LocalModel</span>.<span style="color: #0000FF;">BasicModel</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">System</span>.<span style="color: #0000FF;">Configuration</span>.<span style="color: #0000FF;">ConfigurationManager</span>.<span style="color: #0000FF;">ConnectionStrings</span><span style="color: #000000;">&#91;</span><span style="color: #808080;">&quot;AdventureWorks&quot;</span><span style="color: #000000;">&#93;</span>.<span style="color: #0000FF;">ConnectionString</span><span style="color: #000000;">&#41;</span>, <span style="color: #0600FF;">this</span><span style="color: #000000;">&#41;</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; </li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">void</span> btnSearch_Click<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._presenter.<span style="color: #0000FF;">ExecuteProductSearch</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">string</span> Presenter.<span style="color: #0000FF;">Views</span>.<span style="color: #0000FF;">IProductSearchView</span>.<span style="color: #0000FF;">SearchText</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> tbSearch.<span style="color: #0000FF;">Text</span>; <span style="color: #000000;">&#125;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #000000;">&#123;</span> tbSearch.<span style="color: #0000FF;">Text</span> = value; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li1">&nbsp;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">int</span> Presenter.<span style="color: #0000FF;">Views</span>.<span style="color: #0000FF;">IProductSearchView</span>.<span style="color: #0000FF;">ResultCount</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #000000;">&#123;</span> lblResultCount.<span style="color: #0000FF;">Text</span> = value.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li1">&nbsp;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; List&lt;Model.<span style="color: #0000FF;">Entities</span>.<span style="color: #0000FF;">Product</span>&gt; Presenter.<span style="color: #0000FF;">Views</span>.<span style="color: #0000FF;">IProductSearchView</span>.<span style="color: #0000FF;">SearchResults</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>value != <span style="color: #0600FF;">null</span> &amp;&amp; value.<span style="color: #0000FF;">Count</span> &gt; <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rptProducts.<span style="color: #0000FF;">DataSource</span> = value;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rptProducts.<span style="color: #0000FF;">DataBind</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">bool</span> Presenter.<span style="color: #0000FF;">Views</span>.<span style="color: #0000FF;">IProductSearchView</span>.<span style="color: #0000FF;">DisplayResults</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #000000;">&#123;</span> tblResults.<span style="color: #0000FF;">Visible</span> = value; <span style="color: #000000;">&#125;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">...</li></ol></div><div id="cb47541" style="display: none; color: red;"></div></div></div>

<p>As the presenter populates properties in the view, the information is automatically reflected on the page. The actual logic of how the business functions are called and populate those properties are neatly packaged up in the Presenter and View interface and very little logic occurs in the actual web form.</p>

<div class="codebox"><div class="codeheader"><span>csharp</span><div class="codebox_javascript_links"><a href="http://blogs.lessthandot.com" onclick="linenumberOnOff('cb14030'); return false;">Line number Off</a> | <a href="http://blogs.lessthandot.com#" onclick="expandCode('cb14030','cb19760'); return false;">Hide</a> | <a href="http://blogs.lessthandot.com#" onclick="selectCode(this); return false;">Select all</a></div></div><!-- we need this dummy div to fix a firefox bug when selecting code lines --><div class="codeholder"><div class="csharp" id="cb14030" style="display: block; color: rgb(0, 0, 0);"><ol><li style="" class="li1"><span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> ProductSearchPresenter : BasePresenter <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">protected</span> Views.<span style="color: #0000FF;">IProductSearchView</span> _view;</li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">public</span> ProductSearchPresenter<span style="color: #000000;">&#40;</span>Model.<span style="color: #0000FF;">IModel</span> model, Views.<span style="color: #0000FF;">IProductSearchView</span> view<span style="color: #000000;">&#41;</span> : <span style="color: #0600FF;">base</span><span style="color: #000000;">&#40;</span>model<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view = view;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">ResultCount</span> = <span style="color: #FF0000;">0</span>;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">DisplayResults</span> = <span style="color: #0600FF;">false</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ExecuteProductSearch<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List&lt;Model.<span style="color: #0000FF;">Entities</span>.<span style="color: #0000FF;">Product</span>&gt; results;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results = <span style="color: #0600FF;">this</span>._model.<span style="color: #0000FF;">SearchProduct</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">SearchText</span><span style="color: #000000;">&#41;</span>;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>results.<span style="color: #0000FF;">Count</span> &gt; <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">ResultCount</span> = results.<span style="color: #0000FF;">Count</span>;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">DisplayResults</span> = <span style="color: #0600FF;">true</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">SearchResults</span> = results;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">else</span> <span style="color: #000000;">&#123;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">ResultCount</span> = <span style="color: #FF0000;">0</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">DisplayResults</span> = <span style="color: #0600FF;">false</span>;</li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">this</span>._view.<span style="color: #0000FF;">SearchResults</span> = <span style="color: #0600FF;">null</span>;</li><li style="" class="li1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li2">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li><li style="" class="li1">&nbsp; &nbsp; <span style="color: #000000;">&#125;</span></li></ol></div><div id="cb19760" style="display: none; color: red;"></div></div></div>

<p>To create a unit test, we define a simple view that implements the view interface, execute the presenter logic, and verify the properties are populated the way we would expect when the same presenter calls are made from the interface.</p>

<h3>Extending the Architecture Further</h3>
<p>Extending the application to display product search in a different manner would only require the addition of a new interface that also implements the Product Search View. A Silverlight front-end would only require creating the basic project, implementing the product search View, and wiring the new interface controls to the view properties. To replace the direct mode reference with a service reference, we could create a service facade that implemented the IModel interface, connected to a local or remote WCF service behid the scenes to handle the real model logic. And finally, instead of counting on our QA department to test all of the application interactions, we can create unit tests directly against the Presenter and Views to ensure that all of the interactions below the top surface of the application are happening consistently and to our expectation.</p>

<h2>Your Turn</h2>
<p>Getting this much of the architecture working is a good first step. I took a number of shortcuts on the BasicModel class in my example, but I now have a functional Model-View-Presenter application to play with. Hopefully there was enough information in the article to interest you in trying this out on your own. I urge you to read the articles linked in the top of the post (or several more in my <a href="http://delicious.com/tarwn/model-view-presenter" title="Eli's Delicious bookmarks for M-V-P" target="_blank">Model-View-Presentation bookmarks</a>) and come up with your own diagrams and sample project. Even doing a small project will force you to run into questions and considerations you wouldn't have had by simply reading about it, not to mention unrelated tidbits you will pick up along the way (for instance, I also learned about <a href="http://msdn.microsoft.com/en-us/library/ms668604.aspx" title="ObservableCollection at MSDN" target="_blank">ObservableCollections</a> today).</p><div class="item_footer"><p><small><a href="http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/model-view-presenter-looking-at-passive">Original post</a> blogged on <a href="http://lessthandot.com/">LessThanDot</a>.</small></p></div>]]></content:encoded>
								<comments>http://blogs.lessthandot.com/index.php/Architect/DesigningSoftware/model-view-presenter-looking-at-passive#comments</comments>
			<wfw:commentRss>http://blogs.lessthandot.com/index.php/Architect/?tempskin=_rss2&#38;disp=comments&#38;p=889</wfw:commentRss>
		</item>
			</channel>
</rss>
