Skip to main content

Software Quality

Lately I have been following a lot of discussions on software code quality. There seems to be a lack of consensus on what quality means. This is not very surprising, since quality is a very subjective term, it means different things to different people. Here's what it means to me:
I believe every software is created for a specific purpose. The purpose usually defines the forces that act on the software. Most common forces that usually act on any software from a bsiness perspective are:
1. Adaptability - How well will the software adapt to changes
2. Reliability - How often will the software crash
3. Timeliness - How fast can we ship the software
4. Economy - How much will the software cost
5. Performance - Does the software have quick turnaround times
6. Scalability - Will the software continue to be performant if the user base were to increase substantially
7. Usability - How intuitive is it to use the software

These business factors are usually achieved by the following technical factors:
1. Architecture (Assuming OO design)
a. Choice of classes and their responsibilities
b. Coupling between classes
c. Usage of appropriate design patterns
d. Avoiding known anti patterns

2. Code quality
a. Adherence to coding standards
b. Choice of loops and conditionals
c. Algorithms
d. Size of methods (how large are the methods?)
e. Clarity of comments

3. Test coverage
a. Coverage of unit tests
b. Coverage of functional tests
c. Stress tests (for multi-user software)

4. The overall development process
a. Is the development process ad hoc or is it well outlined?
b. If it is well outlined then is it effective?
c. Code reviews
d. Build frequency
e. Processes each developer must follow locally before check-ins

Now let's consider each business factor and its relation with the technical factors.
Adaptability
1. Architecture
Software adaptability is usually achieved by the right selection of classes and loose coupling between them. This assumes knowledge of what is likely to change. However if we do not know aspects of the system that are likely to change then we could make a matrix of things that we think might change and associate a probability with change case. We can then address the high probability changes in the architecture.
Use of appropriate design patterns will be very useful.
2. Code Quality
We often have to refactor existing code when dealing with changes in business requirements. Two things are involved here. Identifying the code to change and understanding the implications of the change. Choice of appropriate class and method names, keeping methods small and meaningful, and clear comments play an important role in helping us identify code that needs to be refactored. Clear interactions among methods (non-spaghetti code?) will help us identify the implications of the change.
3. Test Coverage
Having a solid test harness will give us immediate feedback of the implication of refactoring.
4. The Overall Process
Regular code reviews ensure code quality, and adequate test coverage.

Reliability
1. Architecture
Architecture probably does not have an important role here.
2. Code Quality
Good coding practices like dealing with and recovering from Exceptions gracefully are very useful to ensure reliability.
3. Test Coverage
Adequate tests are very important to ensure reliability.
4. The overall design process
Again code reviews will help ensure adequate test coverage.

Timeliness
This is the tricky one. Let's say it is very important for a customer to deploy the software by a certain date and let us assume that the time is scarce. Before I write ahead, let me make it clear that making timeliness an important priority can be done only by sacrificing other factors. Whether the sacrifice is appropriate is discussed a few paragraphs ahead.
1. Architecture
Not overengineering the architecture will be useful. An overengineered architecture usually means more classes, and will result in a significantly greater effort on coding and writing test cases. In short do not plan for the future. Plan for the current scope, use best practices and go ahead.
2. Code Quality
We surely cannot achieve timeliness by skipping some methods. Assuming that we've got the write the code we've got to write, where can we save time? Perhaps in the thought process. Perhaps in commenting the code. I definiteky will not recommend saving time in the thought process. Commenting on the other hand is something where corners can be cut. Please do not wince at the thought of cutting corners. Atleast not here. We will discuss the concept very soon.
3. Test Coverage
We can produce software quickly if we write fewer test cases. But this has been known to cause more delays in the QA phase. However I sure there is a law of dimishing returns for test coverage - although I not sure where the curve starts flattening.
4. The Overall Process
Keeping the process light will defenitely help. Perhaps reducing the frequency of code reviews or even elliminating them might help.

Economy
1. Architecture
Is there any aspect in the architecture of a software that can help us achieve economy? Maybe this is slightly misplaced, but using open source frameworks or products may reduce costs. I say *may* reduce costs because we will first have to calculate the total cost of ownership of the open source software we intend to use before we can determine if it will really reduce costs. Some people may be thinking - but architecture should be generic - how did frameworks and open source products get here? Well from a practical perpective I am not sure if architecture can be truly generic. If we were making a web based application using Struts, then we will identify Action classes and ActionForm classes. The choice of these classes has been dictated by Struts. Were we using Turbine or Spring then we would have designed the application slightly differently. I strongly believe that the design of an application is infuenced by the choice of frameworks and other third party products.
Again keeping the architecture simple will help us reduce development costs.
2. Code Quality
Here economy translates into time spent on developing the software. The priciples we identified for timeliness apply here too.
3. Test Coverage
Here economy translates into time spent on developing the software. The priciples we identified for timeliness apply here too. Choice of open source testing frameworks might again help us. However it is important to evaluate their total cost of ownership first.
4. The Overall Process
Certain processes are heavy and also demand the use of expensive tools. I am not sure if there is any clear indication if using such processes and tools add value commensurate to the cost of the tools and other process elements. Again like in 'timeliness', using a light weight process with appropriate, but simple (and open source) tools can reduce the overall cost of developement.

Performance
1. Architecture
Here too I am not very sure if architecture plays a role. Perhaps it does. For example the choice of technology will determine performance. Using EJB's will be slower than using POJO's. But the speed can be enhanced by increasing the resources on the server. There are way too many factors that determine the performance of an application. Architecture cannot be linked with performance in any simplistic way.
2. Code Quality
Code quality is important for performance. We identified algorithms as part of code quality. Most applications have to iterate through object trees to produce an output. Apprpriate algorithms, and database queries play an important role in the overall performance of an application. Having said this I do agree with the widely held belief - "first make it work, then make it fast".
3. Test Coverage
Having appropriate stress tests will help us uncover areas which perform inadequaltely. Test suites will not elliminate performance problems, they will only help us identify them, which is better than the client identifying them.
4. The Overall Process
Again the overall process will contribute only in terms of ensuring proper test coverage. Code reviews might uncover obvious performance issues.

Comments

Popular posts from this blog

Commenting your code

Comments are an integral part of any program, even though they do not contribute to the logic. Appropriate comments add to the maintainability of a software. I have heard developers complain about not remembering the logic of some code they wrote a few months back. Can you imagine how difficult it can be to understand programs written by others, when we sometimes find it hard to understand our own code. It is a nightmare to maintain programs that are not appropriately commented. Java classes should contain comments at various levels. There are two types of comments; implementation comments and documentation comments. Implementation comments usually explain design desicisions, or a particularly intricate peice of code. If you find the need to make a lot of implementation comments, then it may signal overly complex code. Documentation comments usually describe the API of a program, they are meant for developers who are going to use your classes. All classes, methods and variables ...

Inheritance vs. composition depending on how much is same and how much differs

I am reading the excellent Django book right now. In the 4th chapter on Django templates , there is an example of includes and inheritance in Django templates. Without going into details about Django templates, the include is very similar to composition where we can include the text of another template for evaluation. Inheritance in Django templates works in a way similar to object inheritance. Django templates can specify certain blocks which can be redefined in subtemplates. The subtemplates use the rest of the parent template as is. Now we have all learned that inheritance is used when we have a is-a relationship between classes, and composition is used when we have a contains-a relationship. This is absolutely right, but while reading about Django templates, I just realized another pattern in these relationships. This is really simple and perhaps many of you may have already have had this insight... We use inheritance when we want to allow reuse of the bulk of one object in other ...

Planning a User Guide - Part 3/5 - Co-ordinate the Team

Photo by  Helloquence  on  Unsplash This is the third post in a series of five posts on how to plan a user guide. In the first post , I wrote about how to conduct an audience analysis and the second post discussed how to define the overall scope of the manual. Once the overall scope of the user guide is defined, the next step is to coordinate the team that will work on creating the manual. A typical team will consist of the following roles. Many of these roles will be fulfilled by freelancers since they are one-off or intermittent work engagements. At the end of the article, I have provided a list of websites where you can find good freelancers. Creative Artist You'll need to work with a creative artist to design the cover page and any other images for the user guide. Most small to mid-sized companies don't have a dedicated creative artist on their rolls. But that's not a problem. There are several freelancing websites where you can work with great creative ...