Archive for the 'Agile Development' Category

Let design guide, not dictate

Tuesday, May 27th, 2008

A good design should be intended to guide implementation, not dictate it, and for good reason as in the real world of software development requirements and systems are far to complex and dynamic in nature to view a technical design as anything more than a basic prescription intended to form the basis of an efficient implementation. Yet far too often many people seem to believe that once a detailed design has been completed and approved implementation should be a breeze; however this is just not a very realistic expectation.

For instance, one of my core job responsibilities is to review technical design documents and provide feedback and direction. This is an iterative process which typically has between 1-3 iterations depending on the complexity of the system. Initially an engineer is given requirements for review; he/she then begins an initial draft of the design and once completed passes it on to me for review. I then review the document and provide feedback where applicable, either via annotations to the document itself or by sitting with the developer, which is by far my preferred process. Should modifications be required the developer will then make revisions as needed. This process is repeated until final design has been approved. At first it may appear as if only a single iteration of design and review would be needed, however more often than not, requirements may not be completely understood during the beginning stages of design, nor are they set in stone so it is very common that a design will need to change during the early stages of a project or even throughout the entire development stage. Once final design has been completed an engineer then begins implementing the design. Theoretically this may appear to be a quite simple process: create a great design which contains as much detail as possible, review it, make revisions and approve it, then just pass it off to any old developer to implement and that’s it, done - wrong!

There are a number of problems to this approach. Below I have outlined the three I feel are most significant and the solutions I have found to address each.

  • Creativity
    The first problem is that a design which goes into too much detail completely limits or even worse, kills creativity - which in my opinion is the single most important trait a developer can possess, especially when designing. The developer is now merely a typist and will undoubtedly become very bored when implementing the design, especially if it is not even his/her design to begin with! Because of this lack of creativity the final code will ultimately suffer and bugs can be expected. Keeping design on a higher level allows developers to have the creative freedom needed to provide quality implementations and work they can feel is their own.
  • Flexibility
    The second problem is that the more detailed and precise the design the less flexibility there is when requirements change and modifications need to be made to the design and thus implementation. For example, if a design contains very low level details, such as method signatures and other implementation specific details the ability to change the design now becomes increasingly complex and will result in much of the design needing to be reworked significantly. In addition the more detail there is the harder it is to write unit tests against the design as the actual implementation has already been defined. Designs need to be very high level and should not go beyond identifying class names, their responsibilities, relationships and dependencies.
  • Tools
    The third problem, which is probably the single most consistent problem I have recognized in my experiences is that far too often developers get caught up in all the details of UML notation and related tools. Again this negates creativity and results in the developer concentrating more on making the design look technically correct rather than concentrating on designing towards a great solution to the problem at hand. In addition this also results in unnecessary time being spent to complete the design, time which could be much better spent on something that produces a better pay off for the project. Now this is not to say that UML shouldn’t be used, actually quite the contrary. I strongly feel that a final design must be in UML as a shared language is needed in order for everyone involved in the design and implementation to easily understand the design. I insist on a technique where developers draw out their design in any way that can be easily understood by them without having to give any thought to anything other than the design itself. Only once the design is finished is the use of Visio or other UML tools to be used.
  • The above illustrates the three most common design issues I have encountered, most of which pertain to over detailed designs, as well as the approach I take in addressing each. If you have not encountered any of these issues in your own work than that is generally a good sign, however try to keep them in mind when designing as it will pay off in the end. The important thing to keep in mind when designing is to design for flexibility and simplicity. Less is usually more and the KISS principle, especially when applied to software design will always pay off in the end.

    Web-Based UML Sequence Diagram Generator

    Monday, April 14th, 2008

    If you need to create sequence diagrams quickly and do not have the time to use the more traditional Software Modeling tools; Together, Enterprise Architect, Visio etc. you should take a look at www.websequencediagrams.com.

    This handy little tool is pretty capable for a free web based utility and is very easy to use. It took me just seconds to create the simple sequence diagram below…

    Web-Based UML Sequence Diagram Generator

    So the next time you need to create UML sequence diagrams in a hurry make sure to check out this very useful tool.

    Principle of Least Knowledge

    Saturday, February 2nd, 2008

    One very important (yet often overlooked) design guideline which I advocate is the Principle of least knowledge.

    The Principle of Least knowledge, also known as The law of Demeter, or more precisely, the Law of Demeter for Functions/Methods (LoD-F) is a design principle which provides guidelines for designing a system with minimal dependencies. It is typically summarized as “Only talk to your immediate friends.”

    What this means is a client should only have knowledge of an objects members, and not have access to properties and methods of other objects via the members. To put it in simple terms you should only have access to the members of the object, and nothing beyond that. Think if it like this: if you use more than 1 dot you are violating the principle.

    Consider the following: We have three classes: ClassA, ClassB and ClassC. ClassA has an instance member of type ClassB. ClassB has an instance member of type ClassC. This can be designed in such a way which allows direct access all the way down the dependency chain to ClassC or beyond, as in the following example:

    // ClassA defines a member of type ClassB and provides
    // access to the instance
    public class ClassA
    {
        private var b:ClassB;
       
        public function getB() : ClassB
        {
             return b;
        }
    }

    // ClassB defines a member of type ClassC and provides
    // access to the instance
    public class ClassB
    {
        private var c:ClassC = new ClassC();
       
        public function getC() : ClassC
        {
             return c;
        }
    }

    // ClassC could expose additional members and on and
    // on creating more and more direct dependencies
    public class ClassC
    {
        public someType:SomeType;
        …
    }

    // client implementation
    var a:ClassA = new ClassA();
    var sometype:SomeType = a.getB().getC().someType;
     

    The above example is quite common, however it violates The Principle of Least Knowledge as it creates multiple dependencies, thus reducing maintainability as should the internal structure of ClassA need to change so would all instances of ClassA.

    Now keep in mind that in all software development there are trade-offs to some degree. Sometimes performance trumps maintainability or vice-versa, other times readability trumps both. A perfect example of where you would not want to use The Principle of Least Knowledge is in a Cairngorm ModelLocator implementation. The Cairngorm ModelLocator violates the Principle of least knowledge for good reason - it simply would not be practical to write wrapper methods for every object on the ModelLocator. This is the main drawback of the Principle of least Knowledge; the need to create wrapper methods for each object, which are more formally known as Demeter Transmogrifiers.

    The goal of good software design is to minimize dependencies, and by carefully following the guidelines provided by The Principle of Least Knowledge this becomes much easier to accomplish.

    Flex Unit TestSuiteHelper

    Friday, January 18th, 2008

    Test Driven Development is an essential part of any software project. Leveraging Flex Unit in your Flex and AIR projects is a well known best practice and will inevitably result in less unknowns and provide a much more reliable codebase, however like most things in life that provide value, unit testing comes at a cost: Time.

    In general, writing Unit tests is often an overlooked process as it ultimately equates to an additional level of effort (time) in a project plan. However, writing unit tests should not be over looked for a number of reasons, and in my opinion most importantly because it forces developers to understand what problems the code they write are intended to solve, thus resulting in a better understanding of the problem domain.

    Now without getting into a lengthy discussion about the benefits of Test Driven Development, as there is plenty of information available on the subject, I am going to focus on how to make it easier in Flex.

    Typically when I write a unit test I stub it out and then run the test runner to make sure it fails. I pretty much do this immediately after I write the test and then I see that my test did not come up and realize I never added it to the test suite. Obviously something like adding tests to a test suite can be an automated process which would allow unit tests to be developed a little faster as all that would be needed was to write the test.

    So in an effort to simplify the process of adding tests to a test suite I have developed a TestSuiteHelper which is a simple utility class that automates the process of adding unit tests to a test suite. Rather than manually adding each test the TestSuiteHelper will automate the process simply by invoking a static method and passing in the test class from which you need to extract all of the tests.

    So if you would like to simplify your team’s unit testing workflow feel free to utilize the TestSuiteHelper.