Category: Dev

  • What is good code?

    What is good code?

    – Defining a common language for discussing code quality

    I recently started a new task as Tech Lead for a company that wanted to improve the quality of the code produced by their inhouse team. That immediately posed the question: What is good quality? The question is hard to answer without having a common language for discussing good and bad code. All developers are good at writing if statements, compiling their code and generally transforming the business requirements into software. But taking the helicopter view is definitely not a common task for developers.

    So how do I approach such a task? The first thing I did was to spend a few days looking at the code. Even though the codebase is several thousand lines of code, I can get an overview within a fairly short time period. I looked for common anti patterns, e.g. having database specific items spread around the code, having no obvious component responsibility etc. These things point to architectural problems and they are usually the result of having a product with many technical drivers over time. Each time responsibility change, a new direction is decided, but we rarely have the time to clean up the existing code base.

    With the overview of the code in mind, the next task is to create a common understanding of the anti-patterns and how to avoid creating new anti-patterns while cleaning the existing anti-patterns. One way of approaching this is to shout out loud that the code is crap. But that will rarely do much on team spirit and it will probably not make the developers take ownership of fixing the problems.

    I placed a copy of clean code on the desk of each developer.

    I choose a different approach: First of all, we need to define a common language for what good code is. To do that, I arranged a reading group. I placed a copy of Robert C. Martins fantastic book “Clean Code” on the table of each developer and assigned homework. 3 chapters each week and then a meeting where we go through the major points in the chapters. The responsibility for leading the walkthrough is shifting between developers each week.

    The book starts out on a quite basic level. How to name things, how to structure code etc. As mentioned before, everybody knows how to write an if statement, but it is surprising how few developers consider naming things. To give an example:

    If (numberOfItems > 10 && customerLevel == “Silver” || customerLevel == “Gold”) 
    {...}

    Is very different than

    If (CanCustomerGetDiscount()) 
    {...}

    It is basic, yes, but changing the naming and extracting the if clause is immediately making the code easier to read and code that is easy to read is easy to maintain (or at least a bit more easy).

    The book graduately get more and more advanced and touches areas as class design and unit testing.

    The idea is that we can create a common language and that the team itself is capable of defining what good code is. Even more important, spot bad code. They need to drive the improvement of quality by themselves, making me obsolete. I will assist them in the journey, advice on implementation strategies, feature design etc., but I cannot improve a huge code base alone.

  • Download Free Pester Cheat Sheet

    Download Free Pester Cheat Sheet

    I recently started testing my PowerShell scripts using the Pester framework. The documentation on GitHub is excellent but I was missing a cheat sheet that can be printed and used as a reference while learning.

    So I  created it.

    Download Pester-cheat-sheet 1.0.1 here and share it in your office. If you like it, please give a heads up on twitter.

  • Non-Functional Requirements – The basis of your software architecture

    Non-Functional Requirements – The basis of your software architecture

    We constantly hear that new applications should use the latest and greatest application architecture… A few years ago everybody was implementing SOA and Onion Architecture, now its CQRS,  Micro Services etc. But how do we make a conscious decision on which architecture to choose? The answer is Non-Functional requirements?

    What is Non-Functional requirements?

    The Non-Functional Requirements (NFR’s) is all the requirements that are not directly involved with the functionality of the application or service being implemented. The NFR’s are typically related to:

    • Performance. The expected number of requests that the need to handle. An example on a Performance NFR
      could be:
      Handle 200 requests / pr second on average. Handle 1000 requests / pr second on peak.
    • Security. Any requirements regarding security. This can be regulatory requirements etc. An example could be: All sensitive user data must be encrypted. But security can be graduated. There is a hugh difference between creating a system that registers the trucks of a truck company and a system tbarbed-wire-250822_640hat registers the passport and driver license at a border crossing. Even though both systems might want to secure the data, the consequences of not doing a proper job, is probably a lot worse in the case of passport registration.
    • Maintainability.  (The cost of fixing bugs)
    • Extensibility (The cost of adding new functionality)
    • Testability (How easy it is to test the application)
    • Scalability (How easy we can scale the number of requests, performance etc)
    • Usability (How easy it is to use the application)

    Lawrence Chung has a presentation describing the different types of non functional requirements and ways to classify them.

    When do we identify the NFR’s

    The NFR’s are typically not defined formally and often they are hard to enforce during development and evaluate before deployment. And if the NFR’s are defined, the business owner typically want everything.

    “I want a secure, fast, maintainable system that can be extended and scale.”, 

    quote, The Typical Ignorant Business Person

    This is alright. But it is our job as tech-people to explain the price of the NFR’s and the consequences of ignoring them.

    Following a strict old-school agile methodology, the NFR’s should evolve along with the business requirements. But this have proven to be difficult as the NFR’s have a huge impact on how the system is build. Performance is hard to add as a feature if the system has been build using a slow technology. Security is often very hard to add as a feature Runwaylater – if not thought in from the start of the project, there is a huge chance of lots of open attack vector that can be utilized by evil people.

    A more “modern” Agile approach, especially for larger enterprise systems, is the thought of having an architectural runway before the actual implementation of the business value. The runway is a shorter or longer period of time where the general NFR’s can be identified, the interaction with other systems in the enterprise can be identified etc and a prototype of the application architecture (A walking skeleton) can be implemented to verify the ideas.

    How do we determine the architecture?

    The architecture will, unfortunately, not jump into your arms just because you have defined a se

    Hammer, wrench and screw
    Hammer, Wrench and screw. Its all a matter of the right tool for the right problem.

    t of NFR’s. But the NFR’s can be used to determine the application architecture and the design of the application. If performance is of high performance, and architecture where every call to a service have to go through a service broker, e,g, Biztalk, probably isn’t such a great idea. If the business area is changing a lot, extensibility is of high importance, and a very modular architecture is necessary.

    No matter what, having a broad knowledge of different types of architecture and their strengths and weaknesses is important.

    It is also important to acknowledge that some parts of the business domain might require special treatment, and that could mean that the domain must be implemented in a different way that the rest of the system. If for instance part of the application contains very sensitive data but performance is less important, it might be a good idea to implement this separate from the rest using the proper techniques for that.

    It’s all a matter of using the right hammer for the right type of nail. But if you don’t know what type of nail you’re going to use, you might end up with a screwdriver.

    Note

    NFR’s are not just attached to the general functionality of an application, but also to the individual business requirements which will be handled during a spring. E.g. “The search result must appear within 2 seks.” or “We must be able to process 3000 customers pr. hour between 2am and 5am” are both requirements that are set for a specific user story or feature. And they can be hard to comply with, even though the architecture is well defined up front.

  • Tabbed Page icons are case sensitive

    I have just spend most of an hour to make the app I’m currently doing work on my devices. I have been working in the simulator during development, and everything has been great, but when i deployed to my iPhone, the app just stopped working. I didn’t close down, but it didn’t load completely either.

    I basically started to comment out code, and finally, I got around to a tab page, that i create at startup:

      public classFrontPage : TabbedPage
    {
    public FrontPage()
    {
    this.Title = “Lean Priority”;
    Children.Add(new ProjectOverviewPage());
    Children.Add(new ContentPage() { Title = “Help”, Icon = “help.png”, Content = new Label() { Text = “Foo” } });
    Children.Add(new AboutPage());
    }
    }

    The problem turned out to be the icons. I entered Icon=”help.png”, but the icon in the resource folder was named “Help.png” – with a capital “H”. Apparently the simulator doesn’t care about casing, where the real devices do. The problem is, that you don’t get any errors when the icons can’t be loaded. The app just stops loading.