Skip to main content

Goals of good software design

I have started publishing the section on Object Oriented design, and this has led me to ask some very basic questions of myself:

What are the goals of good software design?

Here are some points that come to mind:

1. Flexibility:
We may have to change the way in which certain things work. The design must be able to accomodate these changes with minimum effort.

2. Extensibility:
The software will need new features. The design must be able to accomodate them easily. Ideally we must be able to add new stuff by adding code and not by modifying existing code, because modifying existing code may break stuff that was already working.

3. Maintainability:
maintainability = Flexibility + Extensibility ?
Perhaps, but also important for maintainability is being able to understand the code. Which can be achieved by assigning appropriate responsibilities to classes, and not abusing inheritance.

These are common, but are there oher goals?

I came accross an article on the net that suggests that the design should be appropriate to the skill level of the team. That is, we should avoid using complex language features if the team in inexperienced, because they may not be able to maintain the code easily. I think this is slightly controversial. Would it not be better to use the complex features (I am assuming that their usage will bring significant benefit), and educate the team on how to use them?

How about Robustness. Can design influence robustness, or is it something that is attributed more to the process (like having a suite of unit tests, etc)?

Where does "Time to deliver" figure? Should it influence design decisions?

Is there anything else that I am missing? 

Will appreciate responses, questions, comments, suggestions, and the like from all my readers.



Notes: This text was originally posted on my earlier blog at http://www.adaptivelearningonline.net
Here are the comments from the original post

COMMENT:
AUTHOR: Mike
EMAIL:
URL:
DATE: 09/29/2006 05:24:59 AM
It's interesting that you should mention "Time To Deliver". I have seen it affect the design on many projects. When there is sufficient time developers create complex design and when deadlines are really close, the design can get quite crappy.

In my opinion both violate the law of appropriate design.

COMMENT:
AUTHOR: Amol Chaudhari
EMAIL:
URL:
DATE: 10/04/2006 12:47:57 PM
Hi Parag,
i think, in our last discussion we forgot the two most important design goals.
1. Correctness : the software should exactly do what it is supposed to do.
2. Robustness: the software should be fault tolerant. it should quickly recover from the unexpected situations.

COMMENT:
AUTHOR: Parag
DATE: 10/04/2006 06:24:43 PM
Hey Amol,
Interesting points. Any thoughts on how we can design a system for correctness and robustness?
Let's take a starting point:

Robustness is how stable a software system is when it runs for a long time, when the user does funny things with it, when the load increases. Many things like memory and resource usage, gracefully handling exceptional conditions, the ability to not let users do incorrect things and many more go into making a software robust. Now taking this as a cueue, can you come up with design decisions that will improve robustness.

Correctness: Does a software do what it is supposed to do? Again this means that the developers have followed the functional specifications. This may not have anything to do with design, but more to do with understanding the clients requirments, not assuming anything, preparing a good functional specification, or user stories, and following them properly. Even some Agile techniques like immediate feedback, and having a client onsite go a long way in achieving correctness.

HTH

COMMENT:
AUTHOR: rahul saxena systems scit
EMAIL:
URL:
DATE: 01/19/2007 08:40:48 AM
this is a great idea.but i think being a student that cost constraint will also come while designing a system because we design what the user wants but after making it if cost exceeds then the repo and work,time resources everything goes waste.so designing as per cost is also one

COMMENT:
AUTHOR: Parag
DATE: 01/19/2007 10:27:49 AM
A good way to ensure that we do not over engineer a system, is to follow the Agile principles of iterative design and "do the simplest thing that works". Even though many purists still like the "heavy up-front architecture" approach, I have found the Agile approach to be far more effective.

--
Parag

COMMENT:
AUTHOR: Aditi
EMAIL:
URL:
DATE: 07/14/2007 09:17:08 AM
I have recently got my first taste of software design.The trickiest part that I identified was assigning responsibilities to the class.
That was because i directly jumped on identifying classes rather than the objects and their responsibilities.
Even though working with object oriented language and framework i violated the very first rule of Object Oriented Design, "First Identify the Objects in the system".
Am still in process of designing "Robust" and "Flexible" design and this blog definitely helps me gain more insight on the concept.
As per my observation, most common mistake made by software professionals is to design as per convenience rather than design for extensibility and flexibility.
This leads to constraints in the system and also quality disaster.
People debate that with high preesure deadline it gets difficult to design a good system.
Thats still remains an open topic for discussion.

COMMENT:
AUTHOR: Parag
DATE: 07/15/2007 08:07:30 AM
Aditi,

You mention that identifying objects and their responsibilities was more important than identifying classes. Can you elaborate a bit more on that.

I agree, designing for convenience usually does not produce good design. I am of the opinion that a good design is "appropriate". A design that is geared towards convenience can make it very difficult to extend, maintain, and change the system.

However when designing for flexibility and extensibility it is important not to go overboard. Because then we may build flexibility for parts that do not need it, leading to very complex design that is hard to understand.

This will probably be the topic of another post, but there are subtle differences in how to design good API's frameworks, and application logic.

The effect of time pressure is also another consideration, but I think that "appropriate design" should balance all these factors.

COMMENT:
AUTHOR: Aditi
EMAIL:
URL:
DATE: 07/16/2007 07:04:53 PM
What I meant by identifying objects was identifying the real world entities. If we are designing an e-Learning solution, Course, ILT Offering, WBT Offering ,Classroom, Instructor , Packages are the objects in the system. We identify common characteristics and relationship between them.
E.g Offering and Course has a one to many relationship and an Offering contanis a Course. Similarty ILT Offering , WBT Offering is a type of offering.
After defining such relationships and association we get a fair knowledge of how objects interact and then we can model them into classes.
I may be missing the links in between.Am still budding.:).

COMMENT:
AUTHOR: Parag
DATE: 07/17/2007 05:41:33 AM
@Aditi
Yes, yes, that's absolutely fine. In fact that is the way to go about things...

--
Regards
Parag

Comments

Unknown said…
I really like his flexibility with deadlines, attentiveness, creative inputs, and motivating personality. san diego landscape architect

Popular posts from this blog

My HSQLDB schema inspection story

This is a simple story of my need to inspect the schema of an HSQLDB database for a participar FOREIGN KEY, and the interesting things I had to do to actually inspect it. I am using an HSQLDB 1.8 database in one of my web applications. The application has been developed using the Play framework , which by default uses JPA and Hibernate . A few days back, I wanted to inspect the schema which Hibernate had created for one of my model objects. I started the HSQLDB database on my local machine, and then started the database manager with the following command java -cp ./hsqldb-1.8.0.7.jar org.hsqldb.util.DatabaseManagerSwing When I tried the view the schema of my table, it showed me the columns and column types on that table, but it did not show me columns were FOREIGN KEYs. Image 1: Table schema as shown by HSQLDB's database manager I decided to search on StackOverflow and find out how I could view the full schema of the table in question. I got a few hints, and they all pointed to

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