Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Walking the System design - I

0.00/5 (No votes)
1 Feb 2013CPOL8 min read 8.1K  
System design.

Introduction

One of the analogies (I beg pardon from “analogy police”) I have for development is borrowed from the traffic. I believe that it is easy to learn how to drive a car, however to drive a car safely and in high traffic one must be aware of traffic rules. We don’t ride car to bump it to the people, rather we do it to reach our destination in a safe and agile manner. There are rules, practices and conventions to follow, without them traffic would be a chaos and commutation will be more painful rather than pleasant.

Software development is basically a translator job. This endeavor of development might span from couple of weeks to month, to years. The basic facts remain the same that everyone is doing his job of translation. Business analyst is translating stakeholders thoughts in to user stories, developers are translating user stories in to working code, SQA is translating it into test cases. A functional bug is generally a miss in translation. As close as we are to the production date, our bug fixing cost is that much high. These translations are again validated using the unit tests, integration tests and UAT (User Acceptance Testing).

In this article I would like to share my experience and learning’s which I have gained during my journey, I have not reached the destination yet. I would like to exchange thoughts with fellows so that we can learn from each other. This article is focused at anyone who is learning to developing software.

Find out various components involved

I remember when I started my career and I was a just a college pass out, I was very much passionate about coding a piece of functionality. My passion kept me awake for so many nights until I realized that a good focus and change in my development habit can make me more productive.

As soon as someone approaches me and asks me to do a particular task, all my listening skills were at their least. I was translating requirement in my brain. I was mapping the things on the fly. I was good, however the problem was as soon as I found that one particular point in requirement is new to me, I am not aware of pattern/model to solve it; I would stop listening to requirement and start doing a dry code in my brain. I would not listen to requirement any more, rather will listen to the fictitious schema and API calls running at the back of my mind. I am not sure how many people had done the same thing. This resulted in a very poor development cycle, because I need to go to the person again and again and find out more answers. These visits were often too late during the development phase. This yielded in high cost of software.

After doing it couple of times, I started introspecting my behavior. I was curious what am I doing wrong which seems so much right to me, after all if I am not producing good results consistently with in time and budget (Each time every time), I must be missing on something.

That was the ‘Aha’ moment of my life when I found that instead of focusing on how, I should be focusing on what first. I need to note down what needs to be done, I can always find out better ways around how to do it. So equipped with this new thought process. I started focusing on “What needs to be done” first. I started focusing on the components as a block, which might be required for my design. I started appreciating the Lego blocks.

Find out a higher level flow among components

Once I have the components blocks, I started finding out the flow or communication among them. I was very much sure that blocks cannot live in isolation; they must be able to talk to each other. The communication among them needs to be crisp and clear. There has to be a PR (Public Relationship officer) for each block. This is actually used by other blocks as a liasoning officer. Components talk to each other using these PR officers (more accurately the public methods). As it is true with public figures that we need to follow certain protocols to meet them. They will be happy to fulfill our request or may be giving us an honorable denial as long as we are following the protocol. We should not be asking them about their personal life. We should not be tweaking the public relation officer by using our less known private connection inside the block (after all it will be unprofessional). In same way our components communication should only be based on the public methods, without any intrinsic and intimate knowledge about its private members.

This brings us to an interesting programming paradigm of low coupling and high cohesion. A coupling is good; however it is good when it is low. I thought about it for a while and tried to figure out why something bad in high quantity is good when it is low. I turned out to the best engineering excellence of the world i.e. human body. I found that in our body we have so many chemicals which are good, but only when they are in limited quantity or with in the limit. Cholesterol for example (I may be completely wrong here, I am not a doctor) is required by our body to do various other functions.

Coming back to our point, without coupling between the components, components will become like isolated islands, and there will be no means of talking to them. This will defeat the original purpose of components being there to help each other and provide services.

What is cohesion? Cohesion is the virtue by which all parts of a component fits together to serve a single purpose. Assigning more than one purpose may bring down the component. Cohesion starts from the component and goes deep till the function level. Where every function tries to do only specific task. Actually it is a bottom up and inside out thing. As long as computer is concerned, it can run any kind of code, however we write code for other human being, who is going to sustain and maintain the system once we are gone. Code should be easily understandable, it should not be a murder mystery to resolve where a debug- Holmes carries a call stack and watch (read as binoculars and spy glass) to find out clues. Code is the best living documentation but it rarely is the best documentation.

Bottom line is every component should have a responsibility to fulfill and all communication to it should happen through the well-defined public functions. The communication among them should have low coupling. My favorite way to achieve it using Entities (will talk about it in some other blog).

Measure twice cut once

I learned that while we are doing software development, the only raw material which we put in is some coffee and snacks and our fingers dancing over the keyboard. This might cause issues; a thoughtful harmony is melodies while a playing of instrument becomes noise. If I adopt the way, I used to develop the software and try to build a door. I will find that I am reordering the wood logs and doing the same tasks repetitively. I might not be measuring the dimensions for the door, but cutting the wood with estimates. I am not looking at the requirements like where door will be used, what is the opening direction, what is the closing direction and what is the top border embroidery design and what is the bottom design. I just cut it, embezzle the decoration, and then only to find that the wall slot is bigger and my entire effort will be in vain, unless I add some kind of supporting wood log, however with that the artistic decoration will be wasted, which was a requirement.

When we often do coding without paying much attention, we do the same thing. As we write code, we get emotionally attached to it. We try to defend it, pretend that there is no bug, assume that it is working and will support future extensions. This attachment often causes the ego clash in team, SQA and code reviewer are looked as devils incarnated to haunt us. We do not realize how ugly it is unless we get a call to fix it or a change request to extend it.

There might be the case that we developed a good code without measuring it twice. However the problem creeps in while we figure out that the we don’t know what to do in a particular “else” condition of code. By doing a white board session, paper work, mocks and discussion, we can find out such hidden details in much advance.

The solid learning or measuring twice is to use paper/pencil, white board and discussions in the team to figure out what will be required. Mock the objects use them to create early prototypes. Jot down your flows on piece of paper, prepare your table schemas on paper, and find out what kind of data is expected from the persistent store. Use blocks, use low coupling and high cohesion to communicate between various modules.

Design Principles to adhere to

Here is the list of principles which we might want to look in to; this is more like common sense. If we start building on this foundation, our software will be safe when hit with the storm of changes, extension and support. I will bring them up in a different post soon.

  • Program to the interfaces not to implementations.
  • Encapsulate whatever varies
  • Favor objects composition over inheritance.
  • SOLID
  • DRY
  • YAGNI.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)