<?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>Laughing Meme &#187; oop</title>
	<atom:link href="http://laughingmeme.org/tag/oop/feed/" rel="self" type="application/rss+xml" />
	<link>http://laughingmeme.org</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 02 Apr 2012 20:12:19 +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>Propel: a non-review</title>
		<link>http://laughingmeme.org/2004/11/02/propel-a-non-review/</link>
		<comments>http://laughingmeme.org/2004/11/02/propel-a-non-review/#comments</comments>
		<pubDate>Tue, 02 Nov 2004 22:24:25 +0000</pubDate>
		<dc:creator>Kellan</dc:creator>
				<category><![CDATA[Aside]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://lm.quxx.info/?p=2609</guid>
		<description><![CDATA[Making me glad we chose to go with DataObjects]]></description>
			<content:encoded><![CDATA[<p>Making me glad we chose to go with DataObjects</p>
<p><a href='http://revjim.net/comments/10165/'>http://revjim.net/comments/10165/</a></p>]]></content:encoded>
			<wfw:commentRss>http://laughingmeme.org/2004/11/02/propel-a-non-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL, and the CASE for Class Table Inheritance</title>
		<link>http://laughingmeme.org/2004/08/14/mysql-and-the-case-for-class-table-inheritance/</link>
		<comments>http://laughingmeme.org/2004/08/14/mysql-and-the-case-for-class-table-inheritance/#comments</comments>
		<pubDate>Sun, 15 Aug 2004 01:08:00 +0000</pubDate>
		<dc:creator>Kellan</dc:creator>
				<category><![CDATA[case]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[eaa]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[Longer]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://lm.quxx.info/?p=883</guid>
		<description><![CDATA[At work we&#8217;re using Class Table Inheritance to model the core data structures of our as yet nameless open source CRM. (actually it has a code name, but I don&#8217;t like it, so we&#8217;ll pretend it&#8217;s nameless) This week as I learned both the name of this pattern, and the SQL to implement it efficiently [...]]]></description>
			<content:encoded><![CDATA[<p>
At <a href="http://groundspring.org">work</a> we&#8217;re using <a href="http://martinfowler.com/eaaCatalog/classTableInheritance.html">Class Table Inheritance</a> to model the core data structures of our as yet nameless open source <acronym title="Community Relationship Management">CRM</acronym>. (actually it has a code name, but I don&#8217;t like it, so we&#8217;ll pretend it&#8217;s nameless)  
</p>

<p><p>
This week as I learned both the name of this pattern, and the SQL to implement it efficiently in MySQL I thought I&#8217;d share some notes on what we&#8217;ve come up with.
</p>
<span id="more-883"></span>
<p>
<h3>Class Table Inheritance</h3>
<acronym title="Class Table Inheritance">CTI</acronym> is a pattern where your schema  hews closely to the your class hierarchy &#8212; you have a table for each class, and object attributes are stored as columns in the table for that class.  This is as opposed to <a href="http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html">Single Table Inheritance</a>, which stores all attributes for every member of an inheritance tree in a single table, or <a href="http://www.martinfowler.com/eaaCatalog/concreteTableInheritance.html">Concrete Table Inheritance</a> which duplicates the inherited fields to each table.
</p>
<p>
We&#8217;re using CTI for a number of reasons, some excellent, and some because that is how our brains work.  One key benefit is we get the ability to operate on heterogenous collections of object. (i.e. display a sorted list of contact objects irrespective of whether they are individuals, organizations, etc.)  The fact that something as fundamental as polymorphism can be difficult to accomplish using other O/R techniques hilights the general difficulty and <a href="http://www.google.com/search?q=impedance+mismatch" title="6 of the first 10 results are about O/R">impedance mismatch</a> of object to relational mapping.
</p>
<p>
There are, however a few challenges involved. 
</p>
<p>
<h3>The Model</h3>
But quickly a trivial mock up of the data model to give us something to play with.  In this model we have 3 classes, a base Contact class, and 2 types of contacts Individual and Organization which inherit from Contact.  In the database we model this as a Contact table, with a primary id, and any fields which the Contact the parent class provides.  Individual and Organization each get their own table, with class specific attributes, plus the primary id from Contact which is both the primary id, and a foreign key into Contact.  For every contact stored in the database there is a record in the Contact table, and a record in either Individual or Organization.
</p>
<p>
<img src="http://laughingmeme.org/img/simple_contact_model.gif" />
</p>
<p>
<h3>Challenge 1:</h3>
How do you retrieve your data now that it is broken across multiple tables?  The obvious (and obviously wrong) solution would be to first select against the Contact table, examine the resulting data, and select against the appropriate children tables. (remember this example is a drastically simplified data model)
</p>
<p>
<h3>Solution 1:</h3>
My current solution is to do a 3 way left outer join, and then instantiate the objects out of fields which aren&#8217;t null.  It can look a bit ugly with large numbers of columns, but is actually pretty simple, and initial benchmarks against a test data set of 1.3 million records suggests it scales nicely.</p>

<pre>
SELECT 
  c.id as id, c.contactType,
  i.firstName, i.lastName,
  o.name as orgName
FROM
  Contact as c
LEFT JOIN Individual as i ON i.id = c.id 
LEFT JOIN Organization as o ON o.id = c.id
</pre>

<p>(And it&#8217;s pretty easy to coax the necessary SQL out of our modified version of <a href="http://pear.php.net/package/DB_DataObject">DB_DataObject</a>. I&#8217;ll demonstrate that in a future entry)
</p>
<p>
<h3>Challenge 2:</h3>
One of the good reasons (in fact the only concrete one I&#8217;ve given you) to go with CTI and its potential added complexity is the desire to sort a mixed list of contact types.   But what do you do when you want to sort on an amorphous concept like &#8220;Name&#8221;?  Individual might sort by &#8220;Lastname, Firstname&#8221;, while we just use &#8220;orgName&#8221; for an organization.  Where is our polymorphism now?
</p>
<p>
One solution would be select all known records, and do sorting and slicing at the application level.  (This is so wrong it makes my head hurt)  Another solution would be store a field like &#8220;sortName&#8221; on Contact, which you could calculate and save on inserts and updates.  This is on the right track.
</p>
<p>
<h3>Solution 2:</h3>
The solution (which <a href="http://blogs.onenw.org/carl">Carl</a> clued me into while we waited to get into the zoo), is to use the <a href="http://dev.mysql.com/doc/mysql/en/Control_flow_functions.html">SQL CASE statement</a> to calculate &#8220;sortName&#8221; on the fly.  Below is our SQL from below with the new logic in green.</p>

<pre>
SELECT 
  c.id as id, c.contactType,
  i.firstName, i.lastName,
  o.name as orgName<span style="color:green;">,
CASE 
 WHEN c.contactType = 'Individual' THEN CONCAT(i.lastName, i.firstName)
 WHEN c.contactType = 'Organization' THEN o.name
END as sortName</span>
FROM
  Contact as c
LEFT JOIN Individual as i ON i.id = c.id 
LEFT JOIN Organization as o ON o.id = c.id
<span style="color:green;">ORDER by sortName</span>
</pre>

<p></p>
<p>
This simply adds a switch statement to your field list conditionally setting the value of sortName.
</p>
<p>
There is nothing quite so satisfying as finding the right tool for the right job.  I&#8217;m currently totally in love with the CASE statement, and think everyone should know about it. (hence this bit of evangelism)
</p>
<p>
Tip: don&#8217;t forget that &#8216;,&#8217; after orgName, I keep forgetting it and wondering why my SQL isn&#8217;t working.
</p>
<p>
So concludes today&#8217;s edition of &#8220;Enterprise Development with MySQL&#8221; (&#8220;Kellan Learns SQL&#8221; didn&#8217;t sound as impressive).  In the near future I hope to get a chance to write up some of the PHP libs we&#8217;ve been building/modifying to support object rich web development techniques, completing the picture. (<acronym title="Objects Linux Apache MySQL PHP">OLamp</acronym> anyone?)
</p>
<p>
<h3>Mixing Metaphors</h3>
Single, and Concrete <acronym title="Table Inheritance">TI</acronym> both have their places, and the good news is you can mix these patterns without much difficulty.  Still I&#8217;m happy with both the flexibility and &#8220;OO-ness&#8221; of Concrete Table Inheritance, and once again impressed by the speed, and power of MySQL. (N.B. we&#8217;re targeting 4.1.x, but these above examples all work with 4.0.16 and 4.0.20)
</p></p>
]]></content:encoded>
			<wfw:commentRss>http://laughingmeme.org/2004/08/14/mysql-and-the-case-for-class-table-inheritance/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Simple Object Access from Smarty</title>
		<link>http://laughingmeme.org/2004/08/05/simple-object-access-from-smarty/</link>
		<comments>http://laughingmeme.org/2004/08/05/simple-object-access-from-smarty/#comments</comments>
		<pubDate>Fri, 06 Aug 2004 07:51:14 +0000</pubDate>
		<dc:creator>Kellan</dc:creator>
				<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[smarty]]></category>

		<guid isPermaLink="false">http://lm.quxx.info/?p=876</guid>
		<description><![CDATA[On one hand it&#8217;s kind of disheartening how much resistance and fear there is towards objects from segments of the PHP community. (hilighted by the recent hostility towards PHP5&#8242;s adding of something resembling a working object model) On the other hand can you blame them when popular tools like Smarty punish you for using object? [...]]]></description>
			<content:encoded><![CDATA[<p>
On one hand it&#8217;s kind of disheartening how much resistance and fear there
is towards objects from segments of the PHP community. (hilighted by the recent
hostility towards PHP5&#8242;s adding of something resembling a working object model)
On the other hand can you blame them when popular tools like Smarty <a
href="http://smarty.php.net/manual/en/advanced.features.php#advanced.features.ob
jects">punish you for using object?</a> 
</p> 

<p><p>
<h3>Transparent, Unified Access</h3>
In the ideal world you could pass an array or an object to <a href="http://smarty.php.net">Smarty</a> and have the access be transparent.  Being able to call methods on objects from your template is immensley useful.  Besides reinforcing your data model you also:
<ol>
  <li>don&#8217;t have to write all those toArray() method to dump your data to Smarty</li>
  <li>can lazy load data as needed</li>
  <li>can provide intelligent formatting without the need to write a Smarty plugin</li>
</ol>
And being able to do it transparently means it is painless to migrate from  using arrays to using objects (e.g. as your traffic grows, you switch to lazy loading objects), or from objects to arrays.  (another way to say it is, having to know the underlying data storage implementation is a clear case of a leaky abstraction)
</p>
<p>
(fyi this &#8220;ideal world&#8221; is also known as <a href="http://template-toolkit.org">Template Toolkit</a>)
</p>
<p>
<h3>SPL</h3>
There is however a way, with a little effort, to achieve this behaviour with Smarty and PHP5.  One of the most useful, and least discussed new features of PHP5, is the <a href="http://www.zend.com/manual/ref.spl.php">SPL</a>, &#8220;a collection of interfaces and classes that are meant to solve standard problems&#8221;, including allowing objects to behave like arrays, using the <a href="http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html">ArrayAccess</a> interface.
</p>
<p>
<h3>A quick example (there are probably better ones)</h3>
</p>
<p>
Say you had a class that you used to help you page through a list of results, and at the bottom of each page you wanted to add a slug like &#8220;Widgets 21-30 of 142&#8243;.
</p>
<p>
One solution would be to assign <code>{$objectType}</code>, <code>{$showingMin}</code>, <code>{$showingMax}</code>, <code>{$totalToShow}</code> (or some such) variables to Smarty, and then have something like the following in your template:
<pre class="code">
{$objectType} {$showingMin}-{$showingMax} of {$totalToShow} in
</pre>
</p>
<p>
But to my eye that seems to clutter up the paging code with assigns, and clutter up the templates with unintuitive markup. (and this is a simple case)
</p>
<p>
Another solution would be to build the string at some point in your code, and pass <b>that</b> to Smarty (making your eventual I18N process just that much more challenging)
</p>
<p>
The third solution is to have your Pager class <em>pretend</em> to be an array, allowing you to add <code>{$page.showStatus}</code> to your templates which Smarty will compile into  <code>$this-><em>tpl</em>vars['page']['showStatus']</code>, and the SPL will intercept and transform into <code>$page->offsetGet('showStatus')</code>;
</p>
<p>
So whats does the Pager class look like?  Well the relevant bits look like:
<pre>
class Pager implements ArrayAccess {
   ...
   function offsetGet($k) {
    if ($this->offsetExists($k)) {
                return $this->$k();
        }
   }</p>

<p>function offsetExists($k) {
       return method_exists($this, $k);
   }</p>

<p>/* set and unset don't do anything */<br />
   function offsetSet($k, $v) {}
   function offsetUnset($k) {}</p>

<p>function showStatus() {
      ...construct status string and return it....
   }
}
</pre>
The offsetGet() method is the intersting piece.  It says, &#8220;take the array access key, and call the method of the same name on that object&#8221;.  Voila, you can now pass objects to templates, and call methods on them. 
</p>
<p>
<h3>A Word About Security</h3>
Generally you trust your template editors, but if calling arbitrary code worries you there are a couple of things you can do.
<ul>
<li>strip all non-word characters from your access key like so:  <code>$key = preg_replace('/\W/', '', $key);</code></li></p>

<p><li> the method calls are already namespaced to the object, but you could quarantine them further by appending a string to them (e.g. &#8216;tmpl<em>&#8216;), in which case your offsetGet() becomes
<pre>
   function offsetGet($k) {
        $k = preg</em>replace('/\W/', '', $k);
    $f = "tmpl<em>$f";
        return $this->$f();
   }
</pre>
(alternately you could use Relection API to limit offsetGet to only exposing methods inherited from some base class, or whatever other creative solution strikes your fancy)</li>
</ul>
</p>
<p>
(Note most of this code was sketched out on my way home tonight, and my spiral bound notebook&#8217;s PHP syntax hilighting is pretty weak not to mention lacks PHP5 support, so there might be some bugs in the above code)
</p>
<p>
<h3>Smarty and Iterators</h3>
Okay, so all that above is about using SPL&#8217;s array interface to allow method access, but what if you want pass iterators to Smarty?  Should just work right?  Unfortunately not.  You see in Smarty&#8217;s <code></em>compile<em>foreach</em>start</code>, arrays are accessed with an <b>explicit</b> array cast, making it impossible to use an iterator.   The quick and dirty solution is to remove this explicit cast.  However Smarty&#8217;s vmethod&#8217;s list .first, and .last won&#8217;t be available.  For that you need this <a href="http://news.php.net/php.smarty.dev/2510">patch sent to the Smarty Dev list</a>. (hasn&#8217;t tested it yet)
</p></p>
]]></content:encoded>
			<wfw:commentRss>http://laughingmeme.org/2004/08/05/simple-object-access-from-smarty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

