DevPinoy.org

A Filipino Developers Community
Welcome to DevPinoy.org Sign in | Join | Help
in Search

cruizer

aspiring to free and open the mind of .NET developers

January 2007 - Posts

  • Introduction to C# and .NET Part 1 slides

    Some of us from the TipidPC community will be holding a small hands-on seminar on C# and the .NET Framework this February 3, Saturday, at 9 am. Details can be found here if you are interested to attend.

    Download the slides here:
    The assumption here is that you know at least some other procedural programming language (C, VB, BASIC, Pascal or whatever). Note also that the slides are not thorough as I expect to fill the gaps with the actual discussion and hands-on exercises on Saturday's event. I am also not particularly sure of the level of knowledge the attendees, so I'll just play it by the ear then.

    I hope you find these useful! See you on Saturday.

  • The Chernobyl Design Pattern

    This nearly made me fall off my chair. Stick out tongue

    In referring to the Office Open XML specification/proposed standard to accommodate a bug in a previous version of Microsoft Excel, this blog entry describes it as an example of the "Chernobyl Design Pattern." I quote: (note: see update below)
    There is something I call the “Chernobyl Design Pattern”, where you take your worst bug, the ugliest part of your code, the part that is so bad, so radioactive that no one can touch it without getting killed, and you make it private and inaccessible, and put a new interface around it, essentially entomb it in concrete so that no one can get close to it. In other words, if you can't fix it, at least contain the damage.

    Of course, those quite old among us recognize the allusion to the Chernobyl disaster in 1986. Let the programmer beware.

    UPDATE: I have misread the original blog. Actually the author said that Microsoft was actually doing worse than settling for the "Chernobyl Design Pattern" by making its mistake propagate all the way to the Office Open XML specification and into all software that will implement the specification should it become a ratified ISO standard. This is just one of the many objections in the software community to the ISO adopting Office Open XML. (ISO has already ratified the OpenDocument Format as ISO 26300, by the way.)

  • Static instances in PHP4

    If you've read my previous posts here, you'll notice that I advocate code testability and TDD. One of the key design concepts in achieving this is "inversion of control" or the dependency injection pattern. While I do mostly .NET stuff these days, I still dabble with PHP projects from time to time. So of course I'll be applying those concepts to PHP as well.

    One thing that I needed to do with PHP was to come up with static references. In particular, I a wanted to create a singleton that serves as my factory. Hmm...some of you may frown on the word "singleton" being mentioned in the same breath as "testability" or "dependency injection" but I wanted to use that pattern so I can ensure that my running page, at any given time, has only one instance of a particular class -- say, my data access object -- and have an easy way to access that instance anywhere.

    While OOP in PHP has been upgraded significantly for version 5, my project was in version 4. PHP4 doesn't support static class members or static classes. Tough luck. But it supported static variables declared inside functions, like this:

    function someFunction($someParameter) {
      static $someStaticVar = 0;
      // do some stuff...
      $someStaticVar++;
      // do some more
      return $someResult;
    }


    So I thought of a workaround to do what I want:

    $settingsArray = array( /* my db settings go here... */ );

    function & getMyStaticFactory() {
      static $myStaticInstance = null;
      if ($myStaticInstance == null) {
        $myStaticInstance = & new Factory();
      }
      return $myStaticInstance;
    }

    class Factory {
      var $myDAL;
      var $someService;

      function Factory() {
       $this->myDAL = null;
       $this->someService = null;
      }
      function & GetDAL() {
        global $settingsArray;
        $singleFactory = & getMyStaticFactory();
        if ($singleFactory->myDAL == null) {
        $singleFactory->myDAL = & new MyDALClass($settingsArray);
        }
        return $singleFactory->myDAL;
      }
      function & GetSomeServiceThatDependsOnDAL() {
        global $settingsArray;
        $singleFactory = & getMyStaticFactory();
        if ($singleFactory->someService == null) {
          $dalToUse = & Factory::GetDAL();
          $singleFactory->someService = & new ServiceClass(&$dalToUse, 
                                              $settingsArray);
        }
        return $singleFactory->someService;
      }
    }


    so what happens now is that for me to be able to retrieve a reference to a global DAL, I just do something like:

    $dalReference = & Factory::GetDAL();

    and to retrieve a reference to a global instance of SomeService and not worry about its dependencies, I can also do:

    $serviceReference = & Factory::GetSomeServiceThatDependsOnDAL();

    OK, so far so good. Remember my last post where I said that PHP probably needs TDD more than other platforms do because of its loose nature? This is where it bit me. I'm using this testing framework for PHP called SimpleTest. So I created a test case like this for my Factory (I know, I know, it's not TDD to do test cases after creating code, but I'm doing this to illustrate this problem with PHP4). It ensures that the references I got are not null (of course) and that they are identical references (pointing to just ONE instance):

    function testThatIHaveOnlyOneDALInstance() {
      $dal1 = & Factory::GetDAL();
      $dal2 = & Factory::GetDAL();
      $this->assertNotNull($dal1);
      $this->assertNotNull($dal2);
      $this->assertReference($dal1, $dal2);
    }


    And guess what...it's failing! Being the enterprising programmer that I am (kapal ng mukha, ha ha), I inserted an echo statement in the getMyStaticFactory() so that I'll know if it's instantiating more than one instance of the Factory. After running the test, I saw that it did instantiate the factory twice.

    So...can we conclude now that stupid old PHP4 does not support static references and the singleton pattern? Not quite. It turns out from the PHP manual that PHP4 implements static variables as references indeed. And if you assign a reference to that static reference (in this case $myStaticInstance), it WON'T! The solution is not to assign a reference to it but just use straight assignment. So the correct function should look like:

    function & getMyStaticFactory() {
      static $myStaticInstance = null;
      if ($myStaticInstance == null) {
        $myStaticInstance = new Factory();
      }
      return $myStaticInstance;
    }


    Note the removal of the ampersand (&) symbol that is used to denote references. Weird, but it worked. So now the tests pass!

    So what did I learn here? First, PHP4 OOP has a lot of gotchas. Avoid it if possible (by going PHP5) if you're used to the way Java and .NET OOP operates. Second, it's great to have test cases validating the correctness of my code.

  • Why tests should be made to fail first, then pass later

    Because it's better than having tests that pass first then fail later. Stick out tongue

    No kidding. This is true. At first I couldn't understand why TDD evangelists would say that a test should start at "red" (or even fail to compile at all) before you put in code that will make the test pass or go "green." I mean, it's a waste of my time, isn't it? I know what I need to do and I don't need to go through this red-then-green sequence when I can go to green immediately.

    It was only recently that I realized why: because a test that passes at first try doesn't give you (as the programmer) confidence that the code is behaving as you intended. It might have passed by sheer serendipity or by the way the test was constructed. On the other hand, failing a test first means you know what you need to accomplish (pass the test) and that your code (under test) lacks the thing that will make it pass. So once you finally get it to green, it means that the code you've put in yields the correct behavior. And taken together with the previous test cases (which should still be green, of course), it means that the code is on its way to correctness.

    I shall demonstrate how I came to this realization with sample code in my next post. For a change I'll use PHP for the demonstration. I've come to realize too that PHP needs test-driven code more than anything else, because of its loose and typeless nature. More on that later!
    Posted Jan 15 2007, 05:26 PM by cruizer with 3 comment(s)
    Filed under: ,
  • Continuous Integration rocks; AnkhSVN sucks

    I'm midway into my second week at my new employer, and I must say that continuous integration is great. Everyone is quickly in sync and there's immediate feedback that you don't get when you're not using CI. I must admit that since it's my first time to work with CruiseControl.NET, I was intimidated at first and very hesitant to do my first "check-in dance." True enough, my first check-in resulted in a red CCTray icon on the system tray, meaning the build is broken. Stick out tongue I was able to gather enough wits to find the location of the problem, do another check-in dance then see a green icon a few minutes later. Smile

    Meanwhile, AnkhSVN sucks. Well the idea is nice but the implementation isn't stellar. I did a commit using it (since it's integrated into Visual Studio) but it only committed the source files, not the .csproj file. As a result, yep, a broken build because of some missing class which was there anyway! Oh well, I'll just do TortoiseSVN accesses when working with our Subversion repository. By the way, it's great to finally be free from the shackles of Visual SourceSafe and its terrible exclusive check out way of doing things.

    Now back to learning about .NET remoting and Windows Forms... Smile
Powered by Community Server (Commercial Edition), by Telligent Systems