<?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>alecmce.com &#187; architecture</title>
	<atom:link href="http://alecmce.com/tag/architecture/feed" rel="self" type="application/rss+xml" />
	<link>http://alecmce.com</link>
	<description></description>
	<lastBuildDate>Fri, 18 May 2012 02:54:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>When is a sub-class appropriate?</title>
		<link>http://alecmce.com/as3/when-is-a-sub-class-appropriate</link>
		<comments>http://alecmce.com/as3/when-is-a-sub-class-appropriate#comments</comments>
		<pubDate>Mon, 15 Feb 2010 17:00:22 +0000</pubDate>
		<dc:creator>alecmce</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[opinion]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[composition]]></category>
		<category><![CDATA[inheritance]]></category>
		<category><![CDATA[Liskov Substitution Principle]]></category>
		<category><![CDATA[polymorphism]]></category>
		<category><![CDATA[Single Responsibility Principle]]></category>

		<guid isPermaLink="false">http://alecmce.com/?p=694</guid>
		<description><![CDATA[My colleague Anatoly and I regularly need to create dialogs which pop-up in front of our application. Anatoly has created a class which allows the dialog to be configured by a packet of data which contains header, any text or images, button labels, footers, and information about how the buttons are processed, like this: Anatoly [...]]]></description>
			<content:encoded><![CDATA[<p>My colleague <a href="http://twitter.com/akarp">Anatoly</a> and I regularly need to create dialogs which pop-up in front of our application. Anatoly has created a class which allows the dialog to be configured by a packet of data which contains header, any text or images, button labels, footers, and information about how the buttons are processed, like this:</p>
<pre class="brush: as3; title: ; notranslate">
public class Dialog extends Sprite
{
	public function Dialog(data:DialogData)
	{
		... composes the dialog according to the data that is passed into it ...
	}
}
</pre>
<h2>Anatoly &#8211; Dialog Composition</h2>
<p>Let&#8217;s say that Anatoly wants to create a dialog in a particular view class (please ignore any other architectural considerations &#8211; I say &#8220;view class&#8221; broadly, hoping not to rile anyone who might shout &#8220;mediator&#8221;, which is beside the point in this case):</p>
<pre class="brush: as3; title: ; notranslate">
public class SomeClassWhereDialogsAreShown
{
	...

	public function onActionWhichTriggersExampleDialog():void
	{
		// this is a simplified structure to avoid complicating the point
		var header:String = &quot;This is Header&quot;;
		var body:String = &quot;This is body&quot;;
		var buttons:Array = [&quot;OK&quot;,&quot;Cancel&quot;];
		var data:DialogData = new DialogData(header, body, buttons);
		var dialog:Dialog = new Dialog(data);

		showDialog(dialog);
	}

	// this is one of many dialogs defined here...
	public function onActionWhichTriggersADifferentDialog():void { ... }
	public function onActionWhichTriggersAThirdDialog():void { ... }
	public function onActionWhichTriggersAFourth():void { ... }
	public function onActionWhichTriggersAFifthDialog():void { ... }
}
</pre>
<p>It is important to note that I have massively over-simplified the DialogData. It could be dozens of lines long, contain nested arguments, and so on. This point becomes part of the discussion later on.</p>
<h2>Me &#8211; Dialog Inheritance</h2>
<p>In contrast, I want to create a dialog sub-class and package away the dialog data:</p>
<pre class="brush: as3; title: ; notranslate">
public class ExampleDialog extends Dialog
{
	public function ExampleDialog()
	{
		// this is a simplified structure to avoid complicating the point
		var header:String = &quot;This is Header&quot;;
		var body:String = &quot;This is body&quot;;
		var buttons:Array = [&quot;OK&quot;,&quot;Cancel&quot;];
		var data:DialogData = new DialogData(header, body, buttons);

		super(data);
	}
}

public class SomeClassWhereDialogsAreShown
{
	public function onActionWhichTriggersExampleDialog():void
	{
		showDialog(new ExampleDialog());
	}
}
</pre>
<p>This approach allows me to encapsulate the ExampleDialog very neatly, though it requires more lines of code than the composition approach. ActionScript is verbose enough without actively seeking to add more lines of code.</p>
<h2>Single Responsibility Principle</h2>
<p>If the dialog needs to be changed, the inheritance approach ensures that the only place that code editing need take place is in the code which relates to the particular dialog. This conforms to the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a>, based on the principle of cohesion: the degree to which lines of code form a single unit of functionality is the extent to which they should be in their own class.</p>
<p>I would argue that creating a particular dialog is a functional unit, especially in user-interface code. Anatoly makes the point that all our dialogs are <em>functionally equivalent</em> (more of which below). I suppose he thinks of functionality in terms of the developer, and I the interface.</p>
<p>OOP Design principles are not inviolate, but they point us towards ways of writing code which lead to more robust code. This principle points towards the dialog configuration data not being defined in the <code>SomeClassWhereDialogsAreShown</code> class. (which is different from saying it supports the inheritance approach!)</p>
<h2>Liskov Substitution Princple</h2>
<p>Creating inheritance chains can be problematic. It might be considered reasonable to create a Square class as a subclass of the Rectangle, like this:</p>
<pre class="brush: as3; title: ; notranslate">
public class Rectangle
{
	...

	public function set width(value:Number):void
	{
		_width = value;
	}

	public function set height(value:Number):void
	{
		_height = value;
	}

	public function get area():Number
	{
		return _width * _height;
	}

}

public class Square extends Rectangle
{
	override public function set width(value:Number):void
	{
		_width = _height = value;
	}

	override public function set height(value:Number):void
	{
		_height = _width = value;
	}
}
</pre>
<p>However, this can cause problems. Imagine, during your code that you utilise Rectangle like this:</p>
<pre class="brush: as3; title: ; notranslate">
public class SomeOtherClass
{
	public function doubleRectangleArea(rectangle:Rectangle):void
	{
		rectangle.width *= 2;
	}
}
</pre>
<p>The <code>doubleRectangleArea</code> method presupposes that the <code>Rectangle</code>&#8216;s <code>width</code> and <code>height</code> properties are independent. Polymorphism allows a <code>Square</code> to be passed into the <code>doubleRectangleArea</code> method, but as configured this would quadruple the square&#8217;s area. The functionality of the <code>doubleRectangleArea</code> method is broken because the Square-Rectangle relationship breaks <a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov Substitution Principle</a> (LSP).</p>
<p>This principle serves as a general warning against inappropriate inheritance. Anatoly invoked it in our discussion as a reason to be cautious about inheritance, but I remain unconvinced &#8211; surely not all inheritance is bad, and I am pretty sure that as things stand, no particular thing about our dialogs violate LSP?</p>
<h2>Function and Configuration</h2>
<p>Let&#8217;s suppose you want to model two cars: A <a href="http://www.topgear.com/uk/honda/jazz">Honda Jazz</a> and a <a href="http://www.topgear.com/uk/lotus/exige/road-test/cup-260">Lotus Exige</a>. The following class structure may be appropriate:</p>
<pre class="brush: as3; title: ; notranslate">
public class Car { ... }

public class HondaJazz extends Car { ... }

public class LotusExige extends Car { ... }
</pre>
<p>If, on the other hand, you have two colours of Honda Jazz, the following structure makes little sense:</p>
<pre class="brush: as3; title: ; notranslate">
public class HondaJazz extends Car { ... }

public class BlueHondaJazz extends HondaJazz { ... }

public class WhiteHondaJazz extends HondaJazz { ... }
</pre>
<p>More sensible would be:</p>
<pre class="brush: as3; title: ; notranslate">
public class HondaJazz extends Car
{
	public function HondaJazz(color:uint) { ... }
}
</pre>
<p>In the case of the two types of car there are clear functional differences: acceleration, top-speed, fuel efficiency, to name a few. In the case of the two jazzes, there are no functional differences, merely different <em>configurations</em>.</p>
<p>Anatoly argues that different dialogs are essentially like different <em>configurations</em>, rather than different <em>functionalities</em>. Therefore, they should all be the same class, but the Dialog should be configured through parameters in its constructor.</p>
<h2>Discussion</h2>
<p>So what is the right approach? The Single Responsibility Principle (SRP) definitely points away from the composition approach, if the class in which the composition is made has many other responsibilities. Anatoly has offered to meet me half-way having conceded this point, instead storing the various configurations in static methods of Dialog, or elsewhere, rather than create a subclass.</p>
<p>To me, this still feels wrong. The Function and Configuration argument is a good one, and points towards no sub-class being created. However, I still feel that the sheer quantity of configuration that some dialogs require start to make the act of configuration feel inappropriate.</p>
<p>Furthermore, if all we are really doing is is configuring the same dialog over and over, then I do not think that the Liskov Substitution Principle (LSP) is a concern. If all dialogs really are functionally equivalent, then how can they violate LSP?</p>
<p>Aesthetically, the inheritance approach feels right to me, but it is important to respect that Anatoly comes from a very different tradition and has been coding a lot longer than me! The discussion was an interesting (and pleasant) one. If any of you can add to it, then I would be delighted to hear your points of view.</p>
]]></content:encoded>
			<wfw:commentRss>http://alecmce.com/as3/when-is-a-sub-class-appropriate/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

