<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Jason Felice's blog</title>
  <link rel="alternate" type="text/html" href="http://www.developerdotstar.com/community/blog/132"/>
  <link rel="self" type="application/atom+xml" href="http://www.developerdotstar.com/community/blog/132/atom/feed"/>
  <id>http://www.developerdotstar.com/community/blog/132/atom/feed</id>
  <updated>2006-08-16T13:03:44-07:00</updated>
  <entry>
    <title>Holding the Creative Tension</title>
    <link rel="alternate" type="text/html" href="http://www.developerdotstar.com/community/node/596" />
    <id>http://www.developerdotstar.com/community/node/596</id>
    <published>2006-09-28T13:55:18-07:00</published>
    <updated>2006-09-28T14:35:45-07:00</updated>
    <author>
      <name>Jason Felice</name>
    </author>
    <category term="Process and Methodology" />
    <summary type="html"><![CDATA[<p>I've been scheming and postulating on this project for a couple months.  I've created and thrown out several plans on incremental ways to migrate the network to be in a ready state to do this.  It has been very difficult to get anything concrete moving. So then a few days ago, I decided to bite the bullet...</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>We have a network infrastructure which supports some ISP services for people in our building, our own LAN, a DMZ, and point-to-point T1 to one of our clients (for which we provide backup Internet access, although the pipe is primarily for off-site data backup).</p>
<p>This network <em>evolved</em>.  Once upon a time, it supported only our own LAN and web application hosting for our customers.  We tacked a little bit on here, run a new wire there as we sign contracts, and we get to today.</p>
<p>Today, we want to put in multihoming and BGP routers with full tables.  Ugh.</p>
<p>I've been scheming and postulating on this project for a couple months.  I've created and thrown out several plans on incremental ways to migrate the network to be in a ready state to do this.  It has been very difficult to get anything concrete moving.</p>
<p>So then a few days ago, I decided to bite the bullet.  I picked one small change: rerouting traffic from our in-house customers through a different way to free up a needed interface on one of our routers.  I wasn't sure how the network had evolved, so I put a little note to diagram the immediately relevant connections and VLANs involved.</p>
<p>I started diagramming, and I couldn't stop.  I claimed the conference room whiteboard.  I seem to have inspired a coworker who is fond of the network side of the business, and we ended up with the whole shebang laid out on the 8' wide, 4' high whiteboard using three different colored markers.</p>
<p>We stared at this for a while.  Alan then fired up his laptop and pulled it into the conference room and began plugging the connections into "neato" (part of the graphviz package).  After a couple hours, we had a new, cleaner diagram.</p>
<p>We used this physical-layer diagram and discussed how to move forward.  Did this diagram challenge any of the assumptions that I'd made in deciding the little piece to move?</p>
<p>It did.  So what to do now?  We threw around a few ideas, but nothing satisfactory.  Then I pulled out a piece of scrap paper and drew out a three-zone system, with redundant routers, and a "forward DMZ."  I put the two diagrams next to each other and saw these two were worlds apart.  No surprise there.</p>
<p>But then, looking back and forth, we found a whole new way to go about this in incremental steps.  It was incredibly obvious.</p>
<p>I am reminded of wisdom which I think came from the Fifth Discipline: Work from deep understanding, and hold the creative tension between the way things currently are, and the reality you'd like to create.</p>
    ]]></content>
  </entry>
  <entry>
    <title>What&#039;s Wrong With (PHP) Globals</title>
    <link rel="alternate" type="text/html" href="http://www.developerdotstar.com/community/node/548" />
    <id>http://www.developerdotstar.com/community/node/548</id>
    <published>2006-08-16T11:29:17-07:00</published>
    <updated>2006-08-16T13:03:44-07:00</updated>
    <author>
      <name>Jason Felice</name>
    </author>
    <category term="Object Oriented Design and Programming" />
    <category term="Open Source Software" />
    <category term="PHP" />
    <category term="Refactoring" />
    <summary type="html"><![CDATA[<p>When I've contributed to projects with fewer global variables, I've noticed that the flexibility and maintainability of the code has been significantly greater, and I have more fun working with it. My theory: if there are no globals, we can predict that an object doesn't play with any toys that we haven't given it.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>When I've contributed to PHP projects with fewer global variables, I've noticed that the flexibility and maintainability of the code has been significantly greater, and I have more fun working with it. My theory: if there are no globals, we can predict that an object doesn't play with any toys that we haven't given it.</p>
<p>With globals, the protocol for usage of an object could be complicated and implicit. Given the class:</p>
<div class="codeblock">
<pre><code><font color="#000000"><font color="#0000BB">&lt;?php<br /></font><font color="#007700">class&nbsp;</font><font color="#0000BB">Foo&nbsp;</font><font color="#007700">{<br />&nbsp; &nbsp; function&nbsp;</font><font color="#0000BB">Foo</font><font color="#007700">(</font><font color="#0000BB">$number</font><font color="#007700">)&nbsp;{&nbsp;...&nbsp;}<br />&nbsp; &nbsp; function&nbsp;</font><font color="#0000BB">doBar</font><font color="#007700">(</font><font color="#0000BB">$number</font><font color="#007700">)&nbsp;{&nbsp;...&nbsp;}<br />}<br /></font><font color="#0000BB">?&gt;</font></font></code></pre></div>
<p>I might reasonably expect the protocol for using this object to be:</p>
<div class="codeblock">
<pre><code><font color="#000000"><font color="#0000BB">&lt;?php<br />$foo&nbsp;</font><font color="#007700">=&nbsp;new&nbsp;</font><font color="#0000BB">Foo</font><font color="#007700">(</font><font color="#0000BB">12</font><font color="#007700">);<br />echo&nbsp;</font><font color="#0000BB">$foo</font><font color="#007700">-&gt;</font><font color="#0000BB">doBar</font><font color="#007700">(</font><font color="#0000BB">47</font><font color="#007700">);<br /></font><font color="#0000BB">?&gt;</font></font></code></pre></div>
<p>when in fact, the protocol could be:</p>
<div class="codeblock">
<pre><code><font color="#000000"><font color="#0000BB">&lt;?php<br />$GLOBALS</font><font color="#007700">[</font><font color="#DD0000">'calculator_helper'</font><font color="#007700">]&nbsp;=&nbsp;new&nbsp;</font><font color="#0000BB">CalculatorHelper</font><font color="#007700">(</font><font color="#DD0000">"pgsql://localhost/db_cache"</font><font color="#007700">);<br /></font><font color="#0000BB">$_SESSION</font><font color="#007700">[</font><font color="#DD0000">'state'</font><font color="#007700">]&nbsp;=&nbsp;</font><font color="#DD0000">'initializing'</font><font color="#007700">;<br /></font><font color="#0000BB">$foo&nbsp;</font><font color="#007700">=&nbsp;new&nbsp;</font><font color="#0000BB">Foo</font><font color="#007700">(</font><font color="#0000BB">12</font><font color="#007700">);<br /></font><font color="#0000BB">$_SESSION</font><font color="#007700">[</font><font color="#DD0000">'state'</font><font color="#007700">]&nbsp;=&nbsp;</font><font color="#DD0000">'calculating'</font><font color="#007700">;<br />echo&nbsp;</font><font color="#0000BB">$foo</font><font color="#007700">-&gt;</font><font color="#0000BB">doBar</font><font color="#007700">(</font><font color="#0000BB">47</font><font color="#007700">);<br /></font><font color="#0000BB">?&gt;</font></font></code></pre></div>
<p>If I were to remove global references, I'd rewrite the interface like this:</p>
<div class="codeblock">
<pre><code><font color="#000000"><font color="#0000BB">&lt;?php<br /></font><font color="#007700">class&nbsp;</font><font color="#0000BB">Foo&nbsp;</font><font color="#007700">{<br />&nbsp; &nbsp; </font><font color="#FF8000">/**<br />&nbsp; &nbsp; &nbsp;*&nbsp;@param&nbsp;CalculatorHelper::&nbsp;$helper<br />&nbsp; &nbsp; &nbsp;*/<br />&nbsp; &nbsp; </font><font color="#007700">function&nbsp;</font><font color="#0000BB">Foo</font><font color="#007700">(&amp;</font><font color="#0000BB">$helper</font><font color="#007700">,&nbsp;</font><font color="#0000BB">$number</font><font color="#007700">)&nbsp;{&nbsp;...&nbsp;}<br />&nbsp; &nbsp; function&nbsp;</font><font color="#0000BB">setState</font><font color="#007700">(</font><font color="#0000BB">$name</font><font color="#007700">)&nbsp;{&nbsp;...&nbsp;}<br />&nbsp; &nbsp; function&nbsp;</font><font color="#0000BB">bar</font><font color="#007700">(</font><font color="#0000BB">$number</font><font color="#007700">)&nbsp;{&nbsp;...&nbsp;}<br />}<br /></font><font color="#0000BB">?&gt;</font></font></code></pre></div>
<p>While not perfect, I'm comfortable that this better communicates the object's protocol.</p>
<p>So, a no-globals rule means:</p>
<ol>
<li>I can reuse objects more confidently in different contexts, since I can trust that it needs only what it explicitly asks for by way of constructor and method call signatures.</li>
<li>I can easily guess what an object depends on by looking at its usage.</li>
<li>I can more easily find method calls and constructions of a class, for adding parameters and refactoring and such.</li>
</ol>
<p><b>Consider What Global?</b></p>
<p>Exercising deft circular reasoning, if removing globals makes explicit which toys an object can play with, we can define a "global" as anything that an object can play with which was not explicitly handed to it.</p>
<p>For these purposes, then, along with variables declared global I consider PHP's autoglobals ($_SESSION, $_REQUEST, $_COOKIES, etc.) to be global, as well as static variables in functions and methods.  This last point requires us to bring in the "Singleton" pattern as a global.</p>
<p>Global state also hides inside some PHP library functions: ini_get() and ini_set() are obvious, but also consider the output buffering functions.  Granted, these don't usually get in the way, since the ini functions are typically used only during initialization and the output buffering functions hide a stack and beg to be used in a balanced fasion within the calling functions&mdash;but so long as I am fleshing out the terrain, let's not avoid the corners.</p>
<p>If it seems like "global temptations" lurk everywhere in PHP, it is because they do.  Unlike Ruby, where globals are rarely seen and introduced by the scary "$", PHP <em>requires</em> the poor coder to use autoglobals to interact with the person at the browser.  The result is that the uncareful developer winds up testing whether $_REQUEST[&#039;flag&#039;] is set smack in the middle of his model code&mdash;and the unit test will catch that sort of error approximately once every never.</p>
<p><b>What To Do?</b></p>
<ul>
<li>Do not use the global keyword <em>ever</em>, unless you plainly cannot help it.  This goes for the $GLOBALS autoglobal as well.</li>
<li>Localize access to autoglobals like $_SERVER and $_SESSION.  I recommend wrapping them in classes anyhow, so that you have another target for the almighty <a href="http://www.refactoring.com/catalog/moveMethod.html">Move Method</a> refactoring.</li>
<li>Avoid the <a href="http://c2.com/cgi/wiki?SingletonPattern">Singleton</a> pattern.  It seems a lot of people react strongly to this&mdash;"But, this is a <a href="http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?z=y&amp;EAN=9780201633610&amp;itm=2">Design Patterns</a> pattern!"  Yes, yes.  I know.  I was lulled into its comfortable sense of problem-solvingness for a period of time.  So I'll give you two options.  Either avoid "Singleton" like the dickens, or buy a really large bottle of buffered analgesic to keep on hand when <em>trying</em> to code your unit tests.</li>
</ul>
<p><b>Refactoring</b></p>
<p>Since I am currently advocating practices to remove the use of global state from the <a href="http://www.horde.org/">Horde Project</a>, I will be posting some articles on small practices (patterns and refactorings) which can be easily ingrained in Open Source contributors.  In other words, more to come!</p>
    ]]></content>
  </entry>
</feed>
