<?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>cakebaker &#187; software engineering</title>
	<atom:link href="http://cakebaker.42dh.com/tags/software-engineering/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Tue, 20 Dec 2011 15:29:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Don&#8217;t change the meaning of parameters</title>
		<link>http://cakebaker.42dh.com/2009/03/15/dont-change-the-meaning-of-parameters/</link>
		<comments>http://cakebaker.42dh.com/2009/03/15/dont-change-the-meaning-of-parameters/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 16:19:14 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=1143</guid>
		<description><![CDATA[Yesterday, Kjell Bublitz (aka m3nt0r) published the following solution for using a blacklist with CakePHP&#8217;s Model::save(): // app/app_model.php class AppModel extends Model { function save($data = null, $validate = true, $fieldList = array(), $blackList = false) { if (!empty($fieldList) &#38;&#38; $blackList) { $fieldList = array_diff(array_keys($this-&#62;schema()), $fieldList); } return parent::save($data, $validate, $fieldList); } } Well, I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, Kjell Bublitz (aka m3nt0r) published the following <a href="http://cakealot.com/2009/03/modelsave-blacklist-in-reply-to-teknoid/">solution for using a blacklist with CakePHP&#8217;s Model::save()</a>: </p>
<pre>
<code>// app/app_model.php
class AppModel extends Model {
    function save($data = null, $validate = true, $fieldList = array(), $blackList = false) {
        if (!empty($fieldList) &amp;&amp; $blackList) {
            $fieldList = array_diff(array_keys($this-&gt;schema()), $fieldList);
        }
        return parent::save($data, $validate, $fieldList);
    }
}</code>
</pre>
<p>Well, I&#8217;m not that happy with his solution ;-)  </p>
<p>Sure, it works. However, it changes the meaning of the third parameter, $fieldList, of Model::save(). By design, it represents a whitelist, i.e. you specify with this parameter, which fields should be saved. With the solution shown above, $fieldList now represents either a whitelist or a blacklist, depending on the value of the new $blackList parameter. And this dependency is not visible in the code. If you see the following statement, and you are used to CakePHP, you automatically assume the third parameter is a whitelist, because that&#8217;s the way you learned it&#8230;</p>
<pre>
<code>$this-&gt;MyModel-&gt;save($this-&gt;data, true, array('fieldA', 'fieldB'), true);</code>
</pre>
<p>Ok, so what&#8217;s a better solution?</p>
<p>I think a better solution would be to leave Model::save() &#8220;untouched&#8221; (i.e. you don&#8217;t override it), and to move the blacklist-to-whitelist transformation functionality into its own method as shown below (though I&#8217;m not sure whether this should be in the AppModel, it probably belongs to a utility class):</p>
<pre>
<code>// app/app_model.php
class AppModel extends Model {
    public function transformToWhitelist($blacklist) {
        return array_diff(array_keys($this-&gt;schema()), $blacklist);
    }
}</code>
</pre>
<p>The advantages of such a solution are: a) it is easier to read, b) it is probably easier to test, and c) you don&#8217;t mix responsibilities (the responsibility of a save() method is to save data, and not to transform a list into another list).</p>
<p>Whether it makes sense to use a blacklist when saving data is a different question. See the discussion on <a href="http://teknoid.wordpress.com/2009/03/11/blacklist-your-model-fields-for-save/">teknoid&#8217;s article</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2009/03/15/dont-change-the-meaning-of-parameters/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Not everything has to be public</title>
		<link>http://cakebaker.42dh.com/2008/07/08/not-everything-has-to-be-public/</link>
		<comments>http://cakebaker.42dh.com/2008/07/08/not-everything-has-to-be-public/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 09:20:39 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=621</guid>
		<description><![CDATA[Yesterday, Felix Geisendörfer recommended in an article not to use private/protected properties and methods and called them &#8220;one of the most stupid concepts of OOP&#8221;. I disagree with him, because visibility is one of the essential concepts of OOP. Let me explain why with a short story. Max and Moritz both own a coke machine. [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, Felix Geisendörfer recommended in an <a href="http://debuggable.com/posts/programming-psychology-ii-private-methods:481ed862-b0d8-4a0e-9247-165c4834cda3">article</a> not to use private/protected properties and methods and called them &#8220;one of the most stupid concepts of OOP&#8221;. </p>
<p>I disagree with him, because visibility is one of the essential concepts of OOP. Let me explain why with a short story. </p>
<p>Max and Moritz both own a coke machine. And both want to make a lot of money with their machines ;-)</p>
<p>Max has a traditional coke machine: its basic functionality is to give you a bottle of coke after you paid for it. And from time to time Max has to replenish the machine with new bottles.</p>
<p>Moritz&#8217; coke machine is slightly different: it doesn&#8217;t contain a front cover (it saves him 100 dollar). You just take a bottle of coke and then you can pay for it. And of course it has to be replenished from time to time by Moritz.</p>
<p>After the first day Max is happy about what he earned with his machine. And what about Moritz? He is depressed. His machine is empty. And the cash box too&#8230;</p>
<p>If we analyze both machines, we see that Max&#8217; machine is successful because it only gives you access to a bottle when you paid for it. </p>
<p>Or to say it more generally: it is often necessary to restrict the access to something. </p>
<p>It is a concept you find everywhere in the real world. You don&#8217;t want that everyone drives with your car, or that everyone can get money from your bank account, and so on.</p>
<p>And so it makes sense to use the same concept in the software engineering world. If I want to model Max&#8217; machine in software, I need a way to show that not everyone can access the bottles. And the same applies at the implementation level. And for this purpose it is essential to be able to distinguish between public and private (plus protected, but it doesn&#8217;t fit in the machine metaphor). </p>
<p>At last I want to recommend the opposite to Felix&#8217; recommendation: Make as much as possible private or protected. Not everything has to be public!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/07/08/not-everything-has-to-be-public/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Implicit vs. explicit APIs</title>
		<link>http://cakebaker.42dh.com/2008/05/01/implicit-vs-explicit-apis/</link>
		<comments>http://cakebaker.42dh.com/2008/05/01/implicit-vs-explicit-apis/#comments</comments>
		<pubDate>Thu, 01 May 2008 09:00:15 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=599</guid>
		<description><![CDATA[When developing an API, one point you have to consider is whether you want to provide an implicit or an explicit API. An explicit API is usually quite self-explanatory, the method name tells you what the method does (at least, if it has a good name). Some examples from the core of CakePHP: Model::findAll($conditions = [...]]]></description>
			<content:encoded><![CDATA[<p>When developing an API, one point you have to consider is whether you want to provide an implicit or an explicit API. </p>
<p>An explicit API is usually quite self-explanatory, the method name tells you what the method does (at least, if it has a good name). Some examples from the core of CakePHP: </p>
<pre>
Model::findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null)  // deprecated
Model::findCount($conditions = null, $recursive = 0)  // deprecated
FormHelper::checkbox($fieldName, $options = array())
FormHelper::submit($caption = null, $options = array())
</pre>
<p>On the other hand, an implicit API doesn&#8217;t tell you what the method does (respectively it does it on a more abstract level):</p>
<pre>
Model::find($type, $options = array())  // new syntax
FormHelper::input($fieldName, $options = array())
</pre>
<p>In the first example, the $type parameter determines what the method does, and in the second example it depends either on the data type of the respective database field or on the value of the &#8220;type&#8221; option. </p>
<p>For you as a developer, implementing an implicit API means a) you have to write more code and b) you have to write more documentation (because you also have to explain what the method does)&#8230; On the other hand, an implicit API allows you to provide a unified API (e.g. Model::find(&#8216;all&#8217;), Model::find(&#8216;count&#8217;), and Model::find(&#8216;list&#8217;) vs. Model::findAll(), Model::findCount(), and Model::generateList()).</p>
<p>For a user, an implicit API is probably more difficult to use than an explicit API, at least in the beginning. For example, if you want to get the number of some records, you first look for a method with &#8220;count&#8221; in its name. With an explicit API you will find the Model::findCount() method, but with an implicit API you probably won&#8217;t discover that Model::find() supports a &#8220;count&#8221; type&#8230; </p>
<p>Anyway, in the end it is up to you to decide which approach better fits to your specific situation. Both approaches have their advantages and disadvantages.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/05/01/implicit-vs-explicit-apis/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Do you really need different ways for doing the same?</title>
		<link>http://cakebaker.42dh.com/2008/03/02/do-you-really-need-different-ways-for-doing-the-same/</link>
		<comments>http://cakebaker.42dh.com/2008/03/02/do-you-really-need-different-ways-for-doing-the-same/#comments</comments>
		<pubDate>Sun, 02 Mar 2008 15:27:19 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2008/03/02/do-you-really-need-different-ways-for-doing-the-same/</guid>
		<description><![CDATA[If you develop an application/library/framework it is sometimes tempting to provide different ways to solve a particular &#8220;problem&#8221;. In CakePHP you can, for example, create a submit button with: echo $form-&#62;submit('Save'); or with: echo $form-&#62;end('Save'); The first snippet shows the generic solution to create a submit button, the second is a shortcut to create such [...]]]></description>
			<content:encoded><![CDATA[<p>If you develop an application/library/framework it is sometimes tempting to provide different ways to solve a particular &#8220;problem&#8221;. In CakePHP you can, for example, create a submit button with:</p>
<pre>
echo $form-&gt;submit('Save');
</pre>
<p>or with:</p>
<pre>
echo $form-&gt;end('Save');
</pre>
<p>The first snippet shows the generic solution to create a submit button, the second is a shortcut to create such a button at the end of a form (plus it closes the form). </p>
<p>At first glance this looks pretty nice. But if you think about it, you will see there is quite a price to pay: you have to write and maintain more code, you have more to document and to teach the users, and the users have more to learn&#8230;</p>
<p>Sometimes it is worth to pay this price, sometimes not. It&#8217;s your decision whether you are willing to pay the price.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/03/02/do-you-really-need-different-ways-for-doing-the-same/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Zero items vs. x items in a view</title>
		<link>http://cakebaker.42dh.com/2007/10/02/zero-items-vs-x-items-in-a-view/</link>
		<comments>http://cakebaker.42dh.com/2007/10/02/zero-items-vs-x-items-in-a-view/#comments</comments>
		<pubDate>Tue, 02 Oct 2007 08:22:49 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[view]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2007/10/02/zero-items-vs-x-items-in-a-view/</guid>
		<description><![CDATA[Probably most applications have a scenario where you have to display either zero items or one or more items. A blog, for example, can contain posts or no posts. If there are no posts, you may want to inform the visitor when the blog will start. In the other case you simply show the posts. [...]]]></description>
			<content:encoded><![CDATA[<p>Probably most applications have a scenario where you have to display either zero items or one or more items. A blog, for example, can contain posts or no posts. If there are no posts, you may want to inform the visitor when the blog will start. In the other case you simply show the posts. As you see, what is shown depends on the number of posts (resp. the number of items).</p>
<p>This leads to the question: Where do you decide what is shown? In the controller or in the view?</p>
<p>One could argument that we have two different views, and so the controller has to decide which view to use. In this case the code would look like:</p>
<pre>
// posts_controller.php
function index() {
    $posts = $this-&gt;Post-&gt;findAll();

    if (!empty($posts)) {
        $this-&gt;set('posts', $posts);
    } else {
        $this-&gt;render('no_posts');
    }
}

// posts/index.ctp
foreach($posts as $post) {
    echo $post['Post']['title'];
}

// posts/no_posts.ctp
Sorry, no posts yet.
</pre>
<p>On the other hand one could argument that the view should decide itself how it will react if there is no data provided. Then the code looks like:</p>
<pre>
// posts_controller.php
function index() {
    $this-&gt;set('posts', $this-&gt;Post-&gt;findAll(););
}

// posts/index.ctp
if (!empty($posts)) {
    foreach($posts as $post) {
        echo $post['Post']['title'];
    }
} else {
    echo "Sorry, no posts yet.";
}
</pre>
<p>I don&#8217;t know which approach is &#8220;better&#8221;, personally I tend to the first approach where the logic is in the controller. </p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2007/10/02/zero-items-vs-x-items-in-a-view/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t implement a known concept differently</title>
		<link>http://cakebaker.42dh.com/2007/09/20/dont-implement-a-known-concept-differently/</link>
		<comments>http://cakebaker.42dh.com/2007/09/20/dont-implement-a-known-concept-differently/#comments</comments>
		<pubDate>Thu, 20 Sep 2007 07:48:46 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2007/09/20/dont-implement-a-known-concept-differently/</guid>
		<description><![CDATA[If you look at the source code of CakePHP you find sometimes a piece of code where you have to say to yourself: &#8220;Wow, that&#8217;s a cool example of a bad practice! That could be used to teach principle x!&#8221; (of course, you will find such examples in other projects, too) I found one such [...]]]></description>
			<content:encoded><![CDATA[<p>If you look at the source code of CakePHP you find sometimes a piece of code where you have to say to yourself: &#8220;Wow, that&#8217;s a cool example of a bad practice! That could be used to teach principle x!&#8221; (of course, you will find such examples in other projects, too)</p>
<p>I found one such example as I used the core class ClassRegistry in a scenario which could be simplified as shown below:</p>
<pre>
class A {
    function id() {
        return 'A';
    }
}

class B {
    function id() {
        return 'B';
    }
}

$a = new A();
$b = new B();

ClassRegistry::addObject('test', $a);
ClassRegistry::addObject('test', $b);

$class = ClassRegistry::getObject('test');
echo $class-&gt;id();
</pre>
<p>What will be the output of this example? As you may guess the output is not &#8220;B&#8221; but &#8220;A&#8221;. Not really what you would expect. If we look at the code of the addObject method (rev. 5671) we see the reason for this result:</p>
<pre>
/**
 * Add $object to the registry, associating it with the name $key.
 *
 * @param string $key	Key for the object in registry
 * @param mixed $object	Object to store
 * @access public
 */
function addObject($key, &#038;$object) {
    $_this =&#038; ClassRegistry::getInstance();
    $key = Inflector::underscore($key);
    if (array_key_exists($key, $_this-&gt;__objects) === false) {
        $_this-&gt;__objects[$key] = &$object;
    }
}
</pre>
<p>An object gets only added to the registry if the respective key is not already used. If the key already exists, nothing happens and no error is thrown. So, to be sure your object gets added, you have to call removeObject() first&#8230; I don&#8217;t know why it was implemented in this way and at the moment I can&#8217;t imagine a reason why it was realized like that.   </p>
<p>Ok, what could be done better? </p>
<p>The easiest and, in my opinion, the best solution is to implement it in the same way other structures to store key/value pairs work, i.e. an object with a certain key gets overwritten if a new object is added with the same key. To get this functionality, only the check for the key existence has to be removed.</p>
<p>If you want to keep the functionality as it is implemented now, then I think you have to do two changes: modify the API comment so that it describes what the method really does, and throw an error if someone tries to add an object with a key that already exists. </p>
<p>The main lesson for me from this example is: <strong>Don&#8217;t implement a known concept differently, unless you have a very good reason to do so.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2007/09/20/dont-implement-a-known-concept-differently/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Lessons learned from loadController(null)</title>
		<link>http://cakebaker.42dh.com/2007/08/23/lessons-learned-from-loadcontrollernull/</link>
		<comments>http://cakebaker.42dh.com/2007/08/23/lessons-learned-from-loadcontrollernull/#comments</comments>
		<pubDate>Thu, 23 Aug 2007 12:12:49 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2007/08/23/lessons-learned-from-loadcontrollernull/</guid>
		<description><![CDATA[Yesterday, I stumbled over the following code snippet in Cake and wondered what it does: loadController(null); If you read that statement, it simply doesn&#8217;t make sense. To load a controller with the name set to null, huch? A look at the API doesn&#8217;t bring any clarification: Loads a controller and its helper libraries. Parameters: string [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, I stumbled over the following code snippet in Cake and wondered what it does:</p>
<pre>
loadController(null);
</pre>
<p>If you read that statement, it simply doesn&#8217;t make sense. To load a controller with the name set to null, huch? A look at the <a href="http://api.cakephp.org/1.2/basics_8php.html#a8f62e4b160eecc070da28963794db57">API</a> doesn&#8217;t bring any clarification:</p>
<pre>
Loads a controller and its helper libraries.
Parameters:
string   $name Name of controller
Returns:
boolean Success
</pre>
<p>So we have to dive into the source code (which we fortunately have) to figure out what&#8217;s going on:</p>
<pre>
function loadController($name) {
    if (!class_exists('AppController')) {
        if (file_exists(APP . 'app_controller.php')) {
            require(APP . 'app_controller.php');
        } else {
            require(CAKE . 'app_controller.php');
        }
    }
    if ($name === null) {
        return true;
    }
    // load the controller
    ...
}
</pre>
<p>And we see that the AppController is loaded.</p>
<p>Why do I show this example here? Not to blame the developer, but because this example teaches us some lessons:</p>
<p><strong>Listen to what your code tells you</strong>: By using (and allowing) &#8220;null&#8221; as parameter for the loadController function our code no longer tells us what it does. It doesn&#8217;t say &#8220;I load the AppController&#8221;, it says &#8220;I load the controller with null as name&#8221;, which is of course nonsense.</p>
<p><strong>DRY (don&#8217;t repeat yourself) applies to API docs, too</strong>: If we compare the API docs for the loadController function with the function signature, we see that the function signature tells us the same as the doc comment, and is therefore redundant.</p>
<p><strong>Mention unobvious stuff in the API docs</strong>: As we have seen, the obvious (and redundant) stuff is in the API docs, whereas the unobvious stuff (= loading the AppController when passing &#8220;null&#8221; as parameter) is not mentioned. So by looking at the API we can&#8217;t figure out the full functionality of the function&#8230;</p>
<p><strong>Don&#8217;t do too much (in a single function)</strong>: If we look at the source code of the loadController function we see that it does two different things: loading the AppController, and loading the specified controller. But as the function is about loading controllers (and not about loading the AppController), it should delegate the loading of the AppController to a loadAppController function. </p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2007/08/23/lessons-learned-from-loadcontrollernull/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The &#8220;Multitype Parameter&#8221; Pattern</title>
		<link>http://cakebaker.42dh.com/2007/06/18/the-multitype-parameter-pattern/</link>
		<comments>http://cakebaker.42dh.com/2007/06/18/the-multitype-parameter-pattern/#comments</comments>
		<pubDate>Mon, 18 Jun 2007 09:18:05 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[pattern]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2007/06/18/the-multitype-parameter-pattern/</guid>
		<description><![CDATA[One of the patterns you find throughout CakePHP is what I call the &#8220;Multitype Parameter&#8221; pattern (maybe there exists an &#8220;official&#8221; name for it, I don&#8217;t know). It allows you to either pass a string or an array as a parameter to a function. An example: $this-&#62;redirect('/users/add'); or $this-&#62;redirect(array('controller' =&#62; 'Users', 'action' =&#62; 'add')); As [...]]]></description>
			<content:encoded><![CDATA[<p>One of the patterns you find throughout CakePHP is what I call the &#8220;Multitype Parameter&#8221; pattern (maybe there exists an &#8220;official&#8221; name for it, I don&#8217;t know). It allows you to either pass a string or an array as a parameter to a function. An example:</p>
<pre>
$this-&gt;redirect('/users/add');

or

$this-&gt;redirect(array('controller' =&gt; 'Users', 'action' =&gt; 'add'));
</pre>
<p>As usual in software engineering, using such a pattern comes with trade-offs. On the one hand you get a flexible interface you can extend very easily by adding new keywords, and which is handy for the user as in the usual case he can simply pass a string whereas in other cases he can pass an array. On the other hand you have to write more code and it becomes more difficult to override a method using this pattern.</p>
<p>I don&#8217;t use that pattern often in my own stuff, but maybe it will be helpful to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2007/06/18/the-multitype-parameter-pattern/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t rely on side effects in your code</title>
		<link>http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/</link>
		<comments>http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/#comments</comments>
		<pubDate>Tue, 07 Nov 2006 16:39:57 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/</guid>
		<description><![CDATA[This post is inspired by a bug I encountered today. As I think it is an instructive bug, I will do a little code review of the relevant parts. Ok, let&#8217;s dive into the code. First a bit of context: // snippet from View::_render() $loadedHelpers = $this-&#62;_loadHelpers($loadedHelpers, $this-&#62;helpers); foreach(array_keys($loadedHelpers) as $helper) { As we move [...]]]></description>
			<content:encoded><![CDATA[<p>This post is inspired by a bug I encountered today. As I think it is an instructive bug, I will do a little code review of the relevant parts. </p>
<p>Ok, let&#8217;s dive into the code. First a bit of context:</p>
<pre>
// snippet from View::_render()
$loadedHelpers = $this-&gt;_loadHelpers($loadedHelpers, $this-&gt;helpers);

foreach(array_keys($loadedHelpers) as $helper) {
</pre>
<p>As we move to the View::_loadHelpers() function, we detect the following statement: </p>
<pre>
return $this-&gt;cakeError('missingHelperFile', array(array(
    'helper' =&gt; $helper,
    'file' =&gt; Inflector::underscore($helper) . '.php',
    'base' =&gt; $this-&gt;base
)));
</pre>
<p>That is a bit weird, as the statement returns an error, but there was no error handling in the previous code snippet. But maybe the cakeError function just returns an empty array, who knows. So let&#8217;s have a look at the cakeError function defined in the Object class:</p>
<pre>
function cakeError($method, $messages) {
    ...
    if (class_exists('AppError')) {
        $error = new AppError($method, $messages);
    } else {
        $error = new ErrorHandler($method, $messages);
    }
    return $error;
}
</pre>
<p>No, the function doesn&#8217;t return an array. Hm. As this function returns an object, and the first snippet expects an array, then there should be some PHP errors when displaying a &#8220;missing helper file&#8221; error. But there are no PHP errors. We find the answer in the ErrorHandler class: it just shows the error message and calls &#8220;exit&#8221; to stop the script execution. And so the returns are never called&#8230;</p>
<p>Well, this solution would work fine as long as it is only used internally (even though it is not very elegant). But the framework allows you to write a custom error handler, and so if you want to handle a &#8220;missing helper file&#8221; error yourself, you get PHP errors when you don&#8217;t use an exit. </p>
<p>That&#8217;s it. I hope you learned something from this example :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/11/07/dont-rely-on-side-effects-in-your-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to understand your problem domain</title>
		<link>http://cakebaker.42dh.com/2006/10/09/how-to-understand-your-problem-domain/</link>
		<comments>http://cakebaker.42dh.com/2006/10/09/how-to-understand-your-problem-domain/#comments</comments>
		<pubDate>Mon, 09 Oct 2006 13:27:48 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[domain model]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/2006/10/09/how-to-understand-your-problem-domain/</guid>
		<description><![CDATA[Before you can start with programming you have to know what application you want to build. It is possible that this is done for you by others and you just get a detailled specification of what you have to implement. On the other hand it is also possible that you are the one who has [...]]]></description>
			<content:encoded><![CDATA[<p>Before you can start with programming you have to know what application you want to build. It is possible that this is done for you by others and you just get a detailled specification of what you have to implement. On the other hand it is also possible that you are the one who has to specify what application to build, either together with a client, if it is a client project, or alone/with your team if it is a product/internal project. Of course, there isn&#8217;t just one way of doing it. So the following is just one possible way.</p>
<p>Let us imagine we want to build a simple blog application (highly imaginative, I know *g*). But what does that mean? As there is no client  we can ask, we have to imagine how the application will be used:</p>
<p>&#8220;The user logs into the application and writes a blog post. When he finishes the post, he adds tags to the post to categorize it. Then he publishes the post.&#8221;<br />
&#8220;The (web) surfer reads the post. and because he wants to add additional information, he writes a comment.&#8221;</p>
<p>As it is a simple blog application, that is everything that can be done with it ;-)</p>
<p>From these requirements we can extract the core objects of our application, which are:</p>
<ul>
<li>User</li>
<li>Post</li>
<li>Tag</li>
<li>Comment</li>
</ul>
<p>Those objects usually have associations among each other, which we can visualize in a domain model (I recommend to use pen and paper to draw the domain model as you will be much faster than using a software tool):<br />
<img src="http://cakebaker.42dh.com/wp-content/uploads/2006/10/blog_domain_model1.png" alt="Domain Model of a simple blog application" /><br />
With the domain model we have an image of the part of the real world that is relevant to our application (the problem domain). Things like foreign keys, id attributes, methods, and other details are not relevant at this level. </p>
<p>The next step is to develop the design based on the domain model. In the CakePHP world this usually means the creation of the database design. But that is outside the scope of this article, and left as an exercise for you ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2006/10/09/how-to-understand-your-problem-domain/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

