<?xml version="1.0" encoding="iso-8859-1"?><rss version="2.0"><channel><title>Posts with &quot;&quot;</title><link>http://www.freeklijten.nl/</link><description></description><language>nl-NL</language><copyright>(c) 2006 Procurios</copyright><lastBuildDate>Wed, 02 Jan 2013 10:35:43 +0100</lastBuildDate><docs>http://blogs.law.harvard.edu/tech/rss</docs><generator>Procurios RSS2 Feed</generator><item><title>SOLID - The D is for Dependency Inversion Principle</title><description>&lt;p&gt;The fifth principle of the five SOLID principles is the Dependency Inversion Principle (DIP). You might expect an article on the ISP first, but I feel the internet is filled with enough posts about SOLID. This one was already finished so I&#039;ll publish it nonetheless :)&amp;nbsp;&lt;/p&gt;&lt;p&gt;The DIP deals with avoiding mixing different levels of abstraction in your code. In this article we will explore the last of these principles in depth.&lt;/p&gt;
&lt;p&gt;As for the previous four, Robert C. Martin took the time to summarize the &lt;a href=&quot;http://www.objectmentor.com/resources/articles/dip.pdf&quot;&gt;Dependency Inversion Principle&lt;/a&gt; for us:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1. High level modules should not depend upon low level modules. Both should depend upon abstractions.&lt;/p&gt;
&lt;p&gt;2. Abstractions should not depend upon details. Details should depend upon abstractions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&#039;s look at an example to clarify this:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;function storeBike()
{
    $Bike = getBikeInformationFromPostRequest();
    writeBikeToMySQLi($Bike);
}

function getBikeInformationFromPostRequest()
{
    //parse $_POST and return a Bike object
}

function writeBikeToMySQLi(Bike $Bike)
{
    //store $Bike in a new MySQLi record
}
&lt;/pre&gt;
&lt;p&gt;Of course this code is extremely trivial but we have managed to create a two line function (storeBike) with an algorithm that is absolutely not reusable. Why is it not reusable? Because a high level action (store a Bike) depends upon two low level actions: parse a request into bike information and save bike information to MySQL.&lt;/p&gt;
&lt;p&gt;If you want to read from something else than $_POST or save to something else than MySQL you have to rewrite the algorithm. Although our algorithm is small and trivial it would be 100% reusable in other cases if the code was refactored to this:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;interface BikeReader
{
    public function read();
}

interface BikeWriter()
{
    public function write(Bike $Bike);
}

function storeBike(BikeReader $Reader, BikeWriter $Writer)
{
    $Bike = $Reader-&amp;gt;read();
    $Writer-&amp;gt;write($Bike);
}
&lt;/pre&gt;
&lt;p&gt;The new code works becuase the high level store function now only depends on abstractions. The same function could be used for reading bikes from a file and write them to output as long as the used BikeReader&amp;nbsp;and BikeWriter implement the interfaces.&lt;/p&gt;
&lt;h2&gt;A more tangible example&lt;/h2&gt;
&lt;p&gt;I want to show you how depending on abstractions makes our lives easier in a larger example. Since we&#039;re going to be loading, updating and storing bikes a lot in our application I would like an Api for that. It would not be such a good idea to write the same queries or perform the same validation over and over.&lt;/p&gt;
&lt;p&gt;In the following example there are two interfaces, one for bike and one for a repository. These are the abstractions details can depend on. Of course we need a detail as well, this will be our Api. This Api is where the logic is! Validation, logging, event triggering, you name it. This is what desperately needs to be tested in every application out there!&lt;/p&gt;
&lt;p&gt;Lets have a look at our first interface:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;interface Bike
{
    /**
     * @return int
     */
    public function getId();

    /**
     * @return string 
     */
    public function getName();

    /**
     * @param int $id
     */
    public function setId($id);

    /**
     * @param string $name
     */
    public function setName($name)

}
&lt;/pre&gt;
&lt;p&gt;The second interface we need is for a class that is able to perform CRUD-like operations on bikes, a repository:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;interface BikeRepository
{
    /**
     * @return int 
     */
    public function create();

    /**
     * @param int $bikeId
     * @return Bike
     */
    public function retrieve($bikeId)

    /**
     * @param Bike $Bike
     * @return bool
     */
    public function update(Bike $Bike);

    /**
     * @param Bike $Bike
     * @return bool
     */
    public function delete(Bike $Bike);
}
&lt;/pre&gt;
&lt;p&gt;Now that we have defined our abstractions we can have a look at our detail. Again, this is where the logic is! For readability I only show a possible update function:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;class BikeApi
{
    private $Repository;

    public function __construct(BikeRepository $Repository)
    {
        $this-&amp;gt;Repository = $Repository;
    }

    /**
     * @param Bike $Bike
     * @return bool
     */
    public function update(Bike $Bike)
    {
        $name = $Bike-&amp;gt;getName();
        $id = $Bike-&amp;gt;getId();

        if (empty($name) || empty($id)) {
            return false;
        }

        if ( ! $this-&amp;gt;BikeRepository-&amp;gt;update($Bike) ) {
            return false;
        }
        
        return true;
    }
}
&lt;/pre&gt;
&lt;h3&gt;What did we gain?&lt;/h3&gt;
&lt;p&gt;Now why did we go to all that trouble of defining interfaces and injecting objects into our BikeApi?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It allows us to change implementation details of one detail without affecting another detail.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The repository that is used by the Bike Api can store the Bike data however it wants to. The business logic is completely detached from the implementation detail of our data storage. Changing the way we store data is a relatively small problem that has no effect outside repositories. As long as the new solution implements the existing interface we even know for sure that our application will keep working (tests remember!).&lt;/p&gt;
&lt;h3&gt;Confusion with dependency injection&lt;/h3&gt;
&lt;p&gt;Dependency inversion is often confused with dependency injection. While they touch similar grounds they are not the same. Dependency inversion is described in the two rules at the very start of this article. Dependency injection is a means to an end.&lt;/p&gt;
&lt;p&gt;We enable dependency inversion by injecting the Repository into the constructor instead of calling &lt;em&gt;new SomeImplementationOfRepository()&lt;/em&gt; inside the Api. With the &quot;new call&quot; we tie the Api to a specific implementation, with the typehinted constructor injection we don&#039;t.&lt;/p&gt;
&lt;p&gt;This brings a second advantage.&amp;nbsp;Since the repository is injected and the interface is type hinted we can replace it with a mock object based on that interface in our tests. This allows us to test the business logic in complete seperation of the rest of the system, which is all we really want to. You can see how easy testing the Api in isolation of the repository is in the two sample tests for the Api below:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;class BikeApiTest
{
    public function testUpdate_whenBikeNameIsNotSet_shouldReturnFalse()
    {
        $RepositoryStub = $this
            -&amp;gt;getMockBuilder(&#039;BikeRepository&#039;)
            -&amp;gt;getMock();
        
        $BikeStub = $this
            -&amp;gt;getMockBuilder(&#039;Bike&#039;)
            -&amp;gt;getMock();
        $BikeStub
            -&amp;gt;expects($this-&amp;gt;any())  
            -&amp;gt;method(&#039;getName&#039;)
            -&amp;gt;will($this-&amp;gt;returnValue(false));

        $BikeApi = new BikeApi($RepositoryStub);
        $result = $BikeApi-&amp;gt;update($BikeStub);

        $this-&amp;gt;assertFalse($result); 
    }

    public function testUpdate_whenBikeRepositoryUpdateFails_shouldReturnFalse()
    {
        $RepositoryStub = $this
            -&amp;gt;getMockBuilder(&#039;BikeRepository&#039;)
            -&amp;gt;getMock();
        $RepositoryStub = $this
            -&amp;gt;expects($this-&amp;gt;any())
            -&amp;gt;method(&#039;update&#039;)
            -&amp;gt;will($this-&amp;gt;returnValue(false));
        
        // Make sure the update does not return false to early by setting up a
        // Bike that does return values for name and id.
        $BikeStub = $this
            -&amp;gt;getMockBuilder(&#039;Bike&#039;)
            -&amp;gt;getMock();
        $BikeStub
            -&amp;gt;expects($this-&amp;gt;any())  
            -&amp;gt;method(&#039;getName&#039;)
            -&amp;gt;will($this-&amp;gt;returnValue(&#039;name&#039;));
        $BikeStub
            -&amp;gt;expects($this-&amp;gt;any())  
            -&amp;gt;method(&#039;getId&#039;)
            -&amp;gt;will($this-&amp;gt;returnValue(&#039;id&#039;));

        $BikeApi = new BikeApi($RepositoryStub);
        $result = $BikeApi-&amp;gt;update($BikeStub);

        $this-&amp;gt;assertFalse($result); 
    }
}
&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;By separating details from other details and writing software that only knows about other parts through interfaces we can create software that enables us to change implementation of parts without breaking or changing other parts. As an added bonus, this decoupling of parts allows us to unit test our code. Don&#039;t be afraid of code that others might find &lt;em&gt;java-esque&lt;/em&gt; if it makes refactoring easier and your test suite larger!&lt;/p&gt;&lt;p&gt;Tags: &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;SOLID&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/SOLID&#039;&gt;SOLID&lt;/a&gt;, &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;architecture&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/architecture&#039;&gt;architecture&lt;/a&gt;, &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;OOP&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/OOP&#039;&gt;OOP&lt;/a&gt;, &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;PHP&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/PHP&#039;&gt;PHP&lt;/a&gt;&lt;/p&gt;</description><link>http://www.freeklijten.nl/home/2013/01/02/SOLID-The-D-is-for-Dependency-Inversion-Principle</link><pubDate>Wed, 02 Jan 2013 10:35:43 +0100</pubDate><guid isPermaLink='true'>http://www.freeklijten.nl/home/2013/01/02/SOLID-The-D-is-for-Dependency-Inversion-Principle</guid></item><item><title>Continuous learning</title><description>&lt;p&gt;A couple of years ago I was still at the Utrecht University of Applied Science&amp;nbsp;(university in short from now on), I detested it. Sure, I liked information science and I like to dabble around, but formal education is something that was obviously not for me. It took me four different educations and a year of working in between to even finish one.&lt;/p&gt;&lt;p&gt;Although I finished with a decent average of an 8 ( a B in letters I guess) I didn&#039;t even enjoy the education I finished (Information Sciences). I&#039;m quite sure the education didn&#039;t quite enjoy me either. The fun part of all this? Ever since I finished my Bachelor of Science I started doing exactly what that same education had been trying to get me to do all this time: learning.&lt;/p&gt;
&lt;p&gt;For a long time I didn&#039;t even know if information science was my cup of tea. Dabbling in PHP and playing some games is something else than full-time programming. Official education didn&#039;t exactly convince me either. The moment I knew I was going to be a programmer was during my first internship (most Dutch universities of applied science have an internship lasting somewhere between a couple of months up to half a year). Suddenly I was building stuff that mattered and went directly to production. The speed at which I was learning, by doing, was astronomical as compared to what I was learning at the university.&lt;/p&gt;
&lt;p&gt;I think there where two things that made up the difference:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;At the university I did not create meaningful things. I&#039;ve, quite literally, built a couple of &quot;employment agency systems&quot;. The idea was that by building a system you learned a new technique, say JDeveloper, Java in general, Java on the web with JSP&#039;s and whatnot, etc. Each time something new arrived, a new simplified meaningless system was built. We built to learn. At my current position I learn to build. I mean this both ways, I am learning stuff so I can build software and I&#039;m learning to build software in general. The difference is astonishing. Switch two words and all of a sudden I like this thing called learning!&lt;/li&gt;
&lt;li&gt;At the university I learned stuff when someone decided it was necessary. I therefore learned a lot about different techniques and tools I will never ever even consider to use. Currently I am learning what I need to learn right now. My attention goes 100% to learning stuff that will be directly useful to me, the current project and the company.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Some nuance is required...&lt;/h2&gt;
&lt;p&gt;Of course I spend time learning stuff that is not directly related to my current position. Lately I&#039;ve tried to be more or less active developing &lt;a href=&quot;http://saffire-lang.org/&quot;&gt;Saffire&lt;/a&gt;. I haven&#039;t put in weeks of work, but every now and then I do something. Which forces me to understand C. Now I will never use C at my current position, but it helps me understand PHP better. It makes me understand a different level of programming languages. I&#039;m convinced this makes me a better programmer in the long run.&lt;/p&gt;
&lt;p&gt;Also, I do understand some stuff needs to be taught. You simply need to understand syntax, datastructures and basic algorithms. But if you like your education because you&#039;re doing something useful there, I&#039;m convinced one is bound to be interested even in such static knowledge transfer.&lt;/p&gt;
&lt;p&gt;I think it would be great if during your education you would build something that was actually used. According to &lt;a href=&quot;http://www.intermediair.nl/vakgebieden/it-internet/komende-jaren-groot-tekort-aan-software-ontwikkelaars&quot;&gt;this article&lt;/a&gt;&amp;nbsp;&lt;span&gt;5.202 students finished their higher education in the field of information science in 2012 in the Netherlands alone. Why can&#039;t they build something? Open source software, the university student management system, grade systems, whatever. Tutor students while learning skills on an actual project. To teach the virtue of testing, let them refactor old code and provide tests for it. Why wouldn&#039;t you use an actual project to learn about database normalisation? If you really want to teach students to create websites in java, at least make sure the site is going live...&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I understand this is a massive undertaking that requires a lot of work from both universities, students, open source projects and other included parties. It will probably remain a lone rant on just on of the many blogs that is hosted on the internet. Still, I like the idea so I get to rant about it :)&lt;/p&gt;
&lt;h2&gt;P.S.&lt;/h2&gt;
&lt;p&gt;This blog was originally going to be something along the lines of the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Khan Academy is brilliant. I never received formal math education, but using Khan Academy&amp;nbsp;I can still learn about algebra, geometry and trigonometry at my own pace and on my own level. Just because I like learning. Khan Academy&amp;nbsp;rocks:&amp;nbsp;&lt;a href=&#039;http://www.freeklijten.nlhttps://www.khanacademy.org/&#039;&gt;https://www.khanacademy.org/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But then I realised the above post and switched topics. Khan Academy is brilliant though!&lt;/p&gt;&lt;p&gt;Tags: &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;random&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/random&#039;&gt;random&lt;/a&gt;, &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;opinion&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/opinion&#039;&gt;opinion&lt;/a&gt;&lt;/p&gt;</description><link>http://www.freeklijten.nl/home/2012/12/21/Continuous-learning</link><pubDate>Fri, 21 Dec 2012 10:03:39 +0100</pubDate><guid isPermaLink='true'>http://www.freeklijten.nl/home/2012/12/21/Continuous-learning</guid></item><item><title>SOLID - The L is for Liskov Substitution Principle</title><description>&lt;p&gt;Between a holiday in the states, buying and redecorating a house and a summer it has been a long time since my last blog entry. It seems about time for a new one :) Today we&#039;ll be dealing with the third principle of SOLID, the Liskov Substitution Principle.&lt;/p&gt;
&lt;p&gt;The Liskov Substitution Principle (LSP) was coined by &lt;a href=&quot;http://en.wikipedia.org/wiki/Barbara_Liskov&quot;&gt;Barbara Liskov&lt;/a&gt; as early as 1987. The principle is very tightly connected to the earlier discussed Open Closed Principle. A good way of adhering to the OCP is understanding and implementing code that uses the Liskov Substitution Principle. In this article we will discover why and how.&lt;/p&gt;&lt;p&gt;Barbara Liskov described the Liskov Substitution Principle&amp;nbsp;as follows in 1988:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What is wanted here is something like the following substitution property: If for each object O1 of type S there is an object O2 of type T such that for all programs P de&amp;#64257;ned in terms of T, the behavior of P is unchanged when O1 is substituted for O2 then S is a subtype of T&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Wow.&lt;/p&gt;
&lt;p&gt;That&#039;s a mouthfull, so lets replace the letters with something more understandable (Note: Raleigh is a UK-base bike manufacturer).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RaleighBike is a subtype of Bike&amp;nbsp;if: &quot;for each object of type RaleigBike there is an object of type Bike&amp;nbsp;and a program that is defined in terms of Bikes&amp;nbsp;does not change its behaviour when Bikes&amp;nbsp;are substituted with RaleighBikes&quot;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Still a mouthfull. This is how Robert C. Martin &lt;a href=&quot;http://www.objectmentor.com/resources/articles/lsp.pdf&quot;&gt;summarized it&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Functions that use pointers or references to base classes must be able to use Objects of derived classes without knowing it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Finally something that is understandable. And if you&#039;ve read the &lt;a href=&quot;http://www.freeklijten.nl/home/2012/05/07/SOLID-the-O-is-for-Open-Closed-Principle&quot;&gt;previous article&lt;/a&gt; on the Open Closed Principle, it should sound somewhat familiar. If you read back the article than the quote above is almost what we accomplished with our code to output the current stock of a bike:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;foreach ($bikes as $Bike) {
    $API = BikeAPIFactory::getBikeAPI($Bike);
    echo $API-&amp;gt;getCurrentStock();
}&lt;/pre&gt;
&lt;p&gt;If you haven&#039;t read the OCP article, here is a small recap for you. To avoid numerous switch statements to different kind of API calls for different brands of bikes, we decided to give each bike brand its own API that had exactly the same function signatures as the others. In the end a factory is used to decide which API should be used for a specific bike object.&lt;/p&gt;
&lt;p&gt;But we have to deal with the trustworthyness of our API&#039;s. We expect them to all implement getCurrentStock, but no one is telling them. If the API&#039;s are a little like me, they might not implement that method untill they&#039;re told to ;) Also we have no common base to reference to (think type hinting in function signatures for instance).&lt;/p&gt;
&lt;h2&gt;Design against abstractions&lt;/h2&gt;
&lt;p&gt;API&#039;s are just like us humans, if we don&#039;t impose some rules, there will be hell to pay. So lets come up with some rules. We can do this by defining an interface or abstract class. Since the Bike API&#039;s all have in common that they receive a Bike and store it in their constructor, I feel it would make sense to make an abstract class out of it, but lets show both:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;interface BikeAPI
{
    public function __construct(Bike $Bike);

    public function getCurrentStock();
}

abstract class BikeAPI
{
    private $Bike;

    public function __construct(Bike $Bike)
    {
        $this-&amp;gt;Bike = $Bike;
    }

    abstract public function getCurrentStock();
}
&lt;/pre&gt;
&lt;p&gt;Our API&#039;s can now either extend the abstract class or implement the interface (choose one though!), in both cases we have ensured that each of our API methods is present and has the same input parameters.&lt;/p&gt;
&lt;p&gt;It seems like we are well on our way of adhering to the Liskov Substution Principle. After all, no code using a RaleighBikeApi object needs to know that it is dealing with a RaleighBikeApi&amp;nbsp;as long as the RaleighBikeApi&amp;nbsp;is a subclass of our parent BikeApi. Right?&lt;/p&gt;
&lt;p&gt;Wrong!&lt;/p&gt;
&lt;p&gt;The signatures of the BikeAPI methods are set now, so the input will not change. There is no way to create an API that does not take a Bike in its constructor for instance.&lt;/p&gt;
&lt;p&gt;But what about return values? There are no rules for return values in the interface nor in the abstract class. We could add some &lt;a href=&quot;http://en.wikipedia.org/wiki/PHPDoc&quot;&gt;comments&lt;/a&gt; with return value hints, but they would be exactly that: hints.&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Design by contract&lt;/h2&gt;
&lt;p&gt;When reading up on the LSP you will soon come accross &lt;a href=&quot;http://en.wikipedia.org/wiki/Bertrand_Meyer&quot;&gt;Bertrand Meyer&#039;s&lt;/a&gt; name and the term &lt;a href=&quot;http://en.wikipedia.org/wiki/Design_by_Contract&quot;&gt;&lt;em&gt;Design by contract&lt;/em&gt;&lt;/a&gt;. This is a programming methodology that defines contracts to ensure (amongst others) a classes&#039;s:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;input and return variables&lt;/li&gt;
&lt;li&gt;preconditions&lt;/li&gt;
&lt;li&gt;postconditions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can see where this touches the LSP. A subclass that changes the return variable for instance, can not be used in algorithm as if it was its parent. If we expect the getCurrentStock to return an array with info and one subclass starts returning a CurrentStock object (with stock for multiple warehouses for instance) we are in trouble. We solved this problem for input variables, but we can not force our API&#039;s to do the same for output variables. This means we need to have conventions in our development team.&lt;/p&gt;
&lt;p&gt;This convention would be the LSP. A subclass may not change input our output, it must not change pre- or postconditions and it should leave the state of &lt;a href=&quot;http://en.wikipedia.org/wiki/Invariant_(computer_science)&quot;&gt;invariants&lt;/a&gt; as they are. This is something programmers will have to start doing, there is no syntax (at least not in PHP) to enforce it, but it is very important when you want to write code that adheres to the Open Closed Principle.&lt;/p&gt;
&lt;h2&gt;Some rulebreaking&lt;/h2&gt;
&lt;p&gt;Let&#039;s look at a small example where the LSP is violated to see what kind of problems it will cause. Gazelle (a dutch bike manufacturer) has started offering a new service. They don&#039;t return the total stock for all their warehouses anymore, instead they return the individual stock per warehouse, so customers can estimate delivery times. If a programmer notices this and wants to use this in a single location we are starting to get into trouble. If he starts refactoring to incorporate the new information in the return value without paying attention to the fact that he is violating the LSP, the code will start to fail on us:&lt;/p&gt;
&lt;pre class=&quot;brush:php&quot;&gt;class GazelleAPI extends BikeAPI
{
    public function getCurrentStock()
    {
        //parse response for stock per warehouse location
        return array(
            &#039;dutchWarehouse&#039; =&amp;gt; $dutchWarehouse,
            &#039;germanWarehouse&#039; =&amp;gt; $germanWarehouse,
        );
    }
}
&lt;/pre&gt;
&lt;p&gt;When running (hopefully) the unit test suite before committing this change, the developer will soon notice that his change is going to cause trouble. All Api calls should return the same kind of information. At a minimum they must all return arrays but it would probably be for the better if the returned some sort of stock object. Right now, unit tests fail and users get presented with the word&amp;nbsp;&lt;strong&gt;array&lt;/strong&gt; instead of the actual stock.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Validating the LSP automatically is not that easy in PHP. There are languages built around the Design by contract paradigm (Eiffel by Bertrand Meyer for one), but PHP is not. There is a &lt;a href=&#039;http://www.freeklijten.nlhttps://github.com/stuartherbert/ContractLib/&#039;&gt;PEAR project&lt;/a&gt; that adds functionality for design by contract though.&lt;/p&gt;
&lt;p&gt;However I feel something else is more important. Robert C. Martin writes in his &lt;a href=&quot;http://www.objectmentor.com/resources/articles/lsp.pdf&quot;&gt;article&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A model, viewed in isolation, can not be&amp;nbsp;meaningfully validated. The validity of a model can only be expressed in terms of its clients.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And that is exactly it. It might seem perfectly valid to change the output of a function, certainly in cases that are less obvious than the one above. But if you don&#039;t look at the system, the software using the component you just changed, all kind of problems may arise. By now it must be clear that adhering to the Open Closed Principle is impossible without the Liskov Substitution Principle.&lt;/p&gt;&lt;p&gt;Tags: &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;PHP&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/PHP&#039;&gt;PHP&lt;/a&gt;, &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;SOLID&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/SOLID&#039;&gt;SOLID&lt;/a&gt;, &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;architecture&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/architecture&#039;&gt;architecture&lt;/a&gt;, &lt;a rel=&#039;tag&#039; title=&#039;Show posts with the tag &quot;OOP&quot;&#039; href=&#039;http://www.freeklijten.nl/tag/OOP&#039;&gt;OOP&lt;/a&gt;&lt;/p&gt;</description><link>http://www.freeklijten.nl/home/2012/09/04/SOLID-The-L-is-for-Liskov-Substitution-Principle</link><pubDate>Tue, 04 Sep 2012 09:01:50 +0200</pubDate><guid isPermaLink='true'>http://www.freeklijten.nl/home/2012/09/04/SOLID-The-L-is-for-Liskov-Substitution-Principle</guid></item></channel></rss>