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

<channel>
	<title>TBNL &#187; design patterns</title>
	<atom:link href="http://www.tibobeijen.nl/blog/tag/design-patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tibobeijen.nl</link>
	<description>...another view on the web and how it's built</description>
	<lastBuildDate>Wed, 06 Jul 2011 19:28:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Catching PHP Exceptions: Except the unexpected</title>
		<link>http://www.tibobeijen.nl/blog/2009/10/26/catching-php-exceptions-except-the-unexpected/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/10/26/catching-php-exceptions-except-the-unexpected/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 11:57:20 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=527</guid>
		<description><![CDATA[PHP Exceptions can greatly assist in implementing various error scenario&#8217;s into an application. Before PHP5 one had to resort to specific return values or drastic measures like trigger_error(). Planning exceptions, I found out, is just as important as class design. At any point where a developer needs to handle the possibility of an exception being [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://us.php.net/manual/en/language.exceptions.php">PHP Exceptions</a> can greatly assist in implementing various error scenario&#8217;s into an application. Before PHP5 one had to resort to specific return values or drastic measures like <a href="http://us.php.net/manual/en/function.trigger-error.php">trigger_error()</a>. Planning exceptions, I found out, is just as important as class design. At any point where a developer needs to handle the possibility of an exception being thrown he needs to know: </p>
<ul>
<li>What Exceptions can I expect?</li>
<li>What Exceptions do I plan to catch?</li>
</ul>
<p>In this post I&#8217;ll show some important aspects to consider when planning exceptions.<br />
<span id="more-527"></span></p>
<h3>The Basic Exception</h3>
<p>Let&#8217;s assume a Soap-based web-service client class used to submit order-data to a supplier&#8217;s web-service. The web-service client throws an exception if required configuration parameters are missing. The actual SoapClient object will be initialized when the first webservice method is called.</p>
<p>Web-service client class:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsSoapClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$config</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$soapClient</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$config</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">initSoapClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toSoapParam</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initSoapClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Configuration error'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SoapClient<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Application code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'config'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClient<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// We need to act on this asap...</span>
    <span style="color: #000088;">$AppError</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">register_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// Redirect to application error page</span>
    <span style="color: #000088;">$Redirect</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In case of a configuration error a redirect is performed to an application-error page. And (just an example) some mechanism is triggered that starts to bug a (or all) developers that there&#8217;s a problem that needs immediate attention. </p>
<h3>Knowing what to catch</h3>
<p>There are of course errors that are less disastrous. Web-services can be down so we need to cope with that, resulting in the modifications below:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsSoapClientException <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClientConfigurationException <span style="color: #000000; font-weight: bold;">extends</span> WsSoapClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClientConnectionException <span style="color: #000000; font-weight: bold;">extends</span> WsSoapClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initSoapClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClientConfigurationException<span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'Configuration error'</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        try <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soapClient</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SoapClient<span style="color: #009900;">&#40;</span>
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span><span style="color: #339933;">,</span> 
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'exceptions'</span><span style="color: #339933;">=&gt;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>SoapFault <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClientConnectionException<span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'Cannot load WSDL: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">config</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">wsdl</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClient<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>WsSoapClientConnectionException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// store the order in a queue to be processed later</span>
    <span style="color: #000088;">$Order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">queue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$Redirect</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Page</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'OrderQueued'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Catch everything, also WsSoapClientConfigurationException</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// We need to act on this asap...</span>
    <span style="color: #000088;">$AppError</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">register_error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// Redirect to application error page</span>
    <span style="color: #000088;">$Redirect</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Two things have changed:</p>
<h4>Extending exception types</h4>
<p>Exception classes have been defined for specific errors. They both extend an Exception class that is specific for the WsSoapClient class. This allows us to catch specific exceptions, like is done with WsSoapClientConnectionException. We could also catch all exceptions directly thrown by WsSoapClient by catching WsSoapClientException. When defining exception types one might take <a href="http://us.php.net/manual/en/spl.exceptions.php">SPL Exceptions</a> as a starting point.</p>
<h4>Rethrowing exceptions</h4>
<p>A SoapFault exception is caught and a WsSoapClientConnectionException is thrown instead. Now one might wonder: Why? Couldn&#8217;t I just as well catch SoapFault in the application code? That brings us to the next section.</p>
<h3>Knowing what to expect</h3>
<p>In the previous example we simply used one WsSoapClient class to handle all web-service related communications. Now imagine that we have different suppliers that (inevitably) offer different types of web-services for us to use. Besides a client that handles Soap we now also need a client that handles XML-RPC.</p>
<p>After reading up a bit on <a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29">Design Patterns</a> we decide to introduce a <a href="http://www.ibm.com/developerworks/library/os-php-designptrns/#N10076">Factory</a> that returns the proper web-service client for the order, which we supply in the method call.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsClientFactory
<span style="color: #009900;">&#123;</span>
    static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getWsClient<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">supplier</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'supplierA'</span><span style="color: #339933;">:</span>
                <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WsSoapClient<span style="color: #009900;">&#40;</span>
                    Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'config'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">soap</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">supplierA</span>
                <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'supplierB'</span><span style="color: #339933;">:</span>
                <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WsXmlRpcClient<span style="color: #009900;">&#40;</span>
                    Registry<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'config'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">xmlrpc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">supplierB</span>
                <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Briefly put: The point of a factory is to avoid the &#8216;new&#8217; keyword by allowing it to return various class instances. To know what callable methods to expect on the returned object, the possible object types need to implement a common interface or extend a common (abstract) class. We define an interface WsClient and let the two client types implement it:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsSoapClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// submitting order to soap webservice</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsXmlRpcClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// submitting order to xml-rpc webservice</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now if we take a look at our original application code it becomes obvious that we are not finished yet.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> WsClientFactory<span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>WsSoapClientConnectionException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Now what if there's a XML-RPC client throwing other exceptions?</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We could catch WsXmlRpcClientConnectException as well but that&#8217;s not the way to go for two obvious reasons:</p>
<ol>
<li>We would be duplicating the code in the catch blocks</li>
<li>If later we need to add a WsEmailClient class, we would need to update both the factory and all the try-catch blocks in the application.</li>
</ol>
<h4>Abstracting exceptions</h4>
<p>As the client types implement a common interface we can also define a set of exceptions that are thrown by all classes implementing that interface:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsClientException <span style="color: #000000; font-weight: bold;">extends</span> Exception <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsClientConfigurationException <span style="color: #000000; font-weight: bold;">extends</span> WsClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsClientConnectionException <span style="color: #000000; font-weight: bold;">extends</span> WsClientException<span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">interface</span> WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The classes implementing WsClient:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> WsSoapClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">initSoapClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initSoapClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConfigurationException</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConnectionException</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">class</span> WsXmlRpcClient implements WsClient
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> submitOrder<span style="color: #009900;">&#40;</span>Order <span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">initXmlRpcClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> initXmlRpcClient<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConfigurationException</span>
        <span style="color: #666666; font-style: italic;">// Might throw: WsClientConnectionException</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The application code retrieving an object from the factory now knows what exception types to expect:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> WsClientFactory<span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
try <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">submitOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>WsClientConnectionException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Now we know what to expect</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Wrapping it up</h3>
<p>What the above shows is that:</p>
<ul>
<li>Throwing a default &#8216;Exception&#8217; is bad practice if you ever want to act on that specific error scenario. Without extending the Exception class you can only catch all or none.</li>
<li>New exceptions can be thrown in catch blocks. That way it&#8217;s possible to prevent unexpected exception types to cross certain application design boundaries.</li>
<li>Once class design involves abstract classes or interfaces it is wise to design exception structures as well and organize them in similar layers of abstraction.</li>
</ul>
<p>Using above &#8216;rules of thumb&#8217; will hopefully help in using exceptions to maximum effect. The above mainly covers the structure of exceptions and not so much functionally that can be added to an exception subclass. Ideas to consider:</p>
<ul>
<li>Adding listeners to an Exception that might write exceptions to a log. Beware though: There&#8217;s probably no need to log &#8216;expected exceptions&#8217; and every disk-write is a small hit on performance.</li>
<li>Adding the caught exception to the new exception that is being re-thrown.</li>
</ul>
<p>Do you think I&#8217;ve left out important parts or are you using (entirely) different exception strategies? Feel free to comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/10/26/catching-php-exceptions-except-the-unexpected/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Controlled initialization of domain objects</title>
		<link>http://www.tibobeijen.nl/blog/2009/07/09/controlled-initialization-of-domain-objects/</link>
		<comments>http://www.tibobeijen.nl/blog/2009/07/09/controlled-initialization-of-domain-objects/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 07:09:44 +0000</pubDate>
		<dc:creator>Tibo Beijen</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[domain model]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.tibobeijen.nl/?p=385</guid>
		<description><![CDATA[In a recent project I&#8217;ve been working on, we have used the &#8216;Domain Model&#8216; to describe and design our application. Doing so we decouple persistency logic from the objects that are being passed around and modified throughout our application: The Domain objects. So what in MVC is often referred to as &#8216;model&#8217; is actually a [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent project I&#8217;ve been working on, we have used the &#8216;<a href="http://en.wikipedia.org/wiki/Domain_model">Domain Model</a>&#8216; to describe and design our application. Doing so we decouple persistency logic from the objects that are being passed around and modified throughout our application: The Domain objects. So what in MVC is often referred to as &#8216;model&#8217; is actually a combination of a persistency layer, a service layer and a Domain layer. The persistency and service layer are also referred to as Data Access Objects: DAO. (As for the why and how of this architecture I recommend the article <a href="http://www.angryobjects.com/2009/03/30/writing-robust-php-backends-with-zend-framework/">Writing robust backends with Zend Framework</a>. For a good description of the DAO concept <a href="http://www.sitecrafting.com/blog/php-patterns-part-ii/">look here</a>). </p>
<p>One of the challenges we were facing was that on one hand we wanted to implement business rules in our Domain objects. In plainish english: On setting or changing properties of the object (like changing a status) we want to validate if that action is allowed. On the other hand we want to be able to initialize an object to whatever state corresponds with the data fetched from the persistency layer. Doing so we found that the business rules got in the way during initialization when fetching it from the persistency layer. So what we were looking for was a way to allow the service layer to construct a Domain object using methods that are hidden from the rest of the code. We found two ways:</p>
<ol>
<li>Reflection (as of PHP 5.3)</li>
<li>A design pattern where the Domain object initializes itself using the provided Service object.</li>
</ol>
<p><span id="more-385"></span></p>
<h3>Das Model: DAO, Domain, Service and Persistency layer</h3>
<p>First lets look at how such a Domain object might look like. See simplified example below of an &#8216;order&#8217;:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Domain_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$orderDate</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$articles</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$customer</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$invoices</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$statusHistory</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getArticles<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setStatus<span style="color: #009900;">&#40;</span>OrderStatus <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// other getters and setters</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The order has properties like it&#8217;s id, a list of articles, the customer that placed the order and the invoice(s) sent. Besides that it has a status history that actually is a stack of subsequent statuses that correspond to the business processes involved. Possible statuses could be:</p>
<ul>
<li>initiated</li>
<li>confirmed</li>
<li>payment_confirmed</li>
<li>articles_deliverable</li>
<li>shipped</li>
<li>onhold_system_error</li>
<li>resolved_system_error</li>
<li>onhold_helpdesk</li>
<li>resolved_helpdesk</li>
<li>cancelled_helpdesk</li>
<li>completed</li>
</ul>
<p>Domain objects are fetched, stored and updated by using methods on Service objects. Those service objects implement the aforementioned &#8216;persistency layer&#8217; (could be PDO, webservices, memory, files, etc.). Services are retrieved from a DAO instance that is fetched from a DAO registry. I&#8217;ll cover that more thoroughly in a later post so I&#8217;ll keep it brief:</p>
<p>Bootstrap:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// bootstrap. setup DAO registry  with </span>
<span style="color: #666666; font-style: italic;">// DAO instance that provides service objects</span>
DAO_Factory<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setInstance</span><span style="color: #009900;">&#40;</span>
	<span style="color: #000000; font-weight: bold;">new</span> DAO_PDO<span style="color: #009900;">&#40;</span><span style="color: #000088;">$initialisedPdo</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Fetching an order by id:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// returns concrete DAO, in this case using PDO for persistency</span>
<span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> DAO_Registry<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
	<span style="color: #666666; font-style: italic;">// the DAO instance returns an 'order' service instance</span>
	<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getServiceOrder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #666666; font-style: italic;">// the service instance provides methods for CRUD type operations</span>
	<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getById</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reqOrderId</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Implementing logic</h3>
<p>Now let&#8217;s illustrate the concept of putting business rules in the Domain object: If a customer contacts the helpdesk with a difficult question, the helpdesk can put the order on hold to prevent shipping. The status &#8216;onhold_helpdesk&#8217; is added to the status history. But (in our imaginary shop) this can&#8217;t be done if the order is already shipped. So the setStatus() method will validate if the status given is actually allowed and only then perform the action.</p>
<p>The setStatus() method in the order class now looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Domain_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... properties and other methods</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setStatus<span style="color: #009900;">&#40;</span>OrderStatus <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// determine if new status is allowed business-wise</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$newStatusAllowed</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #990000;">array_push</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">statusHistory</span><span style="color: #339933;">,</span> <span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Domain_Order_InvalidStatus_Exception<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ... other methods</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Calling the setStatus() method should handle the possible exception:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">try <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setStatus</span><span style="color: #009900;">&#40;</span>
		<span style="color: #000000; font-weight: bold;">new</span> OrderStatus<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'onhold_helpdesk'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> catch <span style="color: #009900;">&#40;</span>Domain_Order_InvalidStatus_Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//  properly handle exception</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>No public access allowed</h3>
<p>To continue the example: If an order is already shipped it can&#8217;t be put on hold. But (at least in this imaginary shop) the other way round goes too: If an order is &#8216;on hold&#8217; the status &#8216;shipped&#8217; can&#8217;t be added. The issue has to be resolved first. From a given state this behaviour is good: invalid actions are prevented. The problem is that the public setters like setStatus() are not suitable for bringing a newly created domain object into it&#8217;s &#8216;persisted&#8217; state. A possible solution might be to add methods that bypass the business logic, but as these methods are used by the service object they need to be public. This is not desired as it allows developers to cut corners that shouldn&#8217;t be cut.</p>
<p>So, back to the start of this post: How to set properties bypassing business-logic?</p>
<h3>1 . ReflectionProperty (PHP 5.3)</h3>
<p>As of PHP 5.3 the <a href="http://www.php.net/manual/en/language.oop5.reflection.php#language.oop5.reflection.reflectionproperty">ReflectionProperty</a> class of the <a href="http://www.php.net/manual/en/language.oop5.reflection.php">reflection API</a> has a method setAccessible() that allows access to protected and protected properties. Accessing the protected id property of the Order class would look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Service
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getById<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// based on the id from the persistency layer </span>
        <span style="color: #666666; font-style: italic;">// data is retreived. In this demo the data is a hash. </span>
        <span style="color: #666666; font-style: italic;">// Now it needs to be put into the newly created </span>
        <span style="color: #666666; font-style: italic;">// Order that is returned.</span>
        <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Order<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$refId</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span>  ReflectionProperty<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Order'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$refId</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAccessible</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$refId</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setValue</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">,</span> <span style="color: #000088;">$persistedData</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// ... set other properties</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$order</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The major drawback of using this technique is that the Service class needs to be aware of the internals of the Order class. So, updating the Order class involves needing to update the Service class as well. This breaks basic concepts of OOP. (For a more useful example of reflectionProperty see <a href="http://sebastian-bergmann.de/archives/831-Freezing-and-Thawing-PHP-Objects.html">this object freezer example</a> by Sebastian Bergmann.</p>
<h3>2. Protected Link Pattern?</h3>
<p>Another way to bypass business-logic on creation without exposing that possibility is to create what could be called a &#8216;protected link&#8217; between the Service and the Order object. See code below:</p>
<p>Service:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Service_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getById<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> Order<span style="color: #339933;">::</span>_init<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> _getInitData<span style="color: #009900;">&#40;</span>Domain_Order <span style="color: #000088;">$order</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// will return 'raw' data (hash/object) as</span>
        <span style="color: #666666; font-style: italic;">// retrieved from the persistency layer</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Domain:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Domain_Order
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ... </span>
    <span style="color: #000000; font-weight: bold;">private</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// no, no, go to the Service</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> _init<span style="color: #009900;">&#40;</span>Service_Order <span style="color: #000088;">$service</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// create brand new instance</span>
        <span style="color: #000088;">$order</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Domain_Order<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// fetch persisted data</span>
        <span style="color: #000088;">$initData</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$service</span><span style="color: #339933;">-&gt;</span>_getInitData<span style="color: #009900;">&#40;</span><span style="color: #000088;">$order</span><span style="color: #339933;">,</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// bring order in it's initial state</span>
        <span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$initData</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$order</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">orderDate</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$initData</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'orderDate'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// etc...</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$order</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
    <span style="color: #666666; font-style: italic;">// ... </span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>A static _init() method, that <em>has</em> access to the Order&#8217;s protected properties, is provided with a Service instance and the id of the Order to be initialized. The static Order method then in turn <em>fetches</em> the data from the Service. The new Order instance is then put into the persisted state by directly setting attributes otherwise not accessible. The initialized instance is then returned to the Service which in turn returns it to the requesting code.</p>
<p>On a first glance this might look more complicated than needed: Instead of using a _getInitData() from the Order class we could also have provided the _init() method with a data object that implements a certain interface. But this leaves open the option to initialize an Order object with manipulated data that is not directly derived from the persistency layer.</p>
<p>What this <em>does </em>achieve is that it is now impossible to manipulate a Domain object bypassing methods that apply business logic. Yet at the same time that business logic doesn&#8217;t get in the way when initializing a Domain object from the Service layer. A benefit compared to the reflection solution is that the Service object doesn&#8217;t need to be aware of the Order&#8217;s internals. The existence of the Domain layer&#8217;s _init() and the Service layer&#8217;s _getInitData() methods are enforced by their respective interfaces or the abstract classes they extend. The design of the transported data (in these examples a hash) can of course also be limited to a certain object type.</p>
<p>A drawback is that there is now a public method _getInitData on the Service layer. In this example the impact thereof is reduced by requiring an instance of Domain_Order but that&#8217;s just sugar (or vinegar so you like): It&#8217;s just an indication for developers that they are on the wrong track when they are directly calling _getInitData().</p>
<p>As said, in later posts I plan to elaborate more on the Service and Persistency layers that are briefly shown here. If anyone knows of other ways to address the issue of &#8216;controlled initialization&#8217; I&#8217;m of course very interested. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.tibobeijen.nl/blog/2009/07/09/controlled-initialization-of-domain-objects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

