Over a million developers have joined DZone.

Practical Software Design - A few thoughts!

DZone's Guide to

Practical Software Design - A few thoughts!

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

This post draws its inspiration from the many religious attempts I have made in the past to follow those golden "Oh you must follow these steps to do design. Else you are doomed". I have tried to use them 'literally' and have come to a conclusion that practical or real life software design is far away from what most of these so called experts claim. Here's my take on what actually happens when you sit down to design a software.

Note: By software design, I mean anything ranging from a small algorithm design to something as big as a framework design. I have come to realize a few things.


  • Visualize what your end software program would look like - Abstraction really comes in handy! 
I feel this is one of the most powerful ways of doing design. Why I say this is, it helps you to think of the design of a software in a way that keeps the options for implementation wide open. I feel that visualizing the outcome of a design activity really helps one think of software design in language that is not something like Java or C++ but plain english. It is kinda doing reverse engineering. You have the end product and start to dissect it component by component and try to visualize how they fit together to make sense. e.g. If I want to design a module that would be basically doing simple template processing like 'find and replace'. I would start off thinking about the problem statement and try to figure out what this module or component should really be doing once it is completed. It's something similar to what one would call analyzing the problem domain. It helps me to think of solving this problem in numerous ways since I have not yet zeroed down on any language or using a specific 'design pattern'. Most of the times this approach helps me in coming up with the right set of interfaces and their contracts. It has helped me model my solutions that make sense when I explain the design to the stakeholders who aren't that technical. The key here is that names you choose for your components or interfaces, classes or methods pretty much make sense and hardly need any explicit explanation. All this happens because I am able to visualize my software both in its entirety as well as in granularity. This kinda helps me fit in the pieces quite well and visualize the solution even before its built.

  • Realizing that tools like UML are only aids to convey your ideas

Sometime back I worked on a project as a software developer. I worked on a module whose design wasn't depicted in any sort of UML. It didn't have those class diagrams or sequence diagrams. But we still managed to pull off the module in a great manner. We in fact ended up reusing it for several other applications. At that time, I wasn't convinced of the above fact and blamed my lead for not producing the above design artifacts. He just smiled at me. I was quite annoyed since I firmly believed that 'Good design means having good UML diagrams and those flashy sequence diagrams'. What I failed to realize was that they were just a means of achieving the goal and not the end in themselves. A few months back I got a chance to be in the shoes of that designer myself. I was really watching myself as to how I would go about this new responsibility. I was seeing if I would religiously follow all those UML diagrams and present them to the stakeholders or would I follow some simple techniques like flowcharts and block diagrams to help them convey my design along with supporting code for APIs and reference implementations. I was in a fix. But subconsciously I chose to do the latter. I never felt that I produced any inferior design by not having UML in my design artifacts (although I did include them later for consistency). I was very much able to convey my design to all the stakeholders. The module was developed and delivered without the so called traditional approaches of design. The bottom line was that tools like UML help in communication since they offer a common language to communicate your intent. But they should never become a bottle neck. Not knowing UML doesn't necessarily disqualify your design although it might be difficult to explain what you want to convey since you might heavily rely on your API docs or reference implementations.

  • Code - The ultimate realization of what's in your brain as 'Design' 
Most often I have relied on the above approach. I feel that the code that culminates at the end, is the ultimate proof of what one thinks/visualizes as design. I feel that as an alternative to relying on tools, one can also resort to coming up with the APIs and reference implementations to explain the design to the stakeholders. Why I feel this to be very practical is because I have found that as time progresses and the code undergoes some changes, most people don't go and update their design documents. Hence the only artifact to understand a module happens to be the code. I feel that a design artifact that hasn't been updated to reflect that latest changes is worse than no design at all. Hence I feel that relying on code to make it self explanatory can be the most practical approach to this problem. Once you have the module that has more or less become stable, you can go ahead and get those artifacts either using reverse engineering or by standard design techniques. Some purists may blame me here and cry foul. But I feel that it doesn't get any real than this. Software design is still very much iterative and you are always going to flesh out so many things from your original design that you might feel that updating that UML diagram is becoming a bottle neck more than anything else. 99% of the time people give up on updating these artifacts owing to time constraints. Hence I feel that it's easy and wise to make those UML diagrams only after you have actually stabilized your design else your going to spend a lot of time on one of those UML tools editing your design!!
  • Refactoring - Do it diligently and mercilessly

I have come to terms with this fact very recently. Some time ago I used to feel that refactoring is actually a sign that you did not design something well. When I think of it now, I can't help but laugh at myself. I now feel that if I can re-factor something easily without breaking too much around my original design (viz having to remove some methods in an API or move a method from one API to another), I have done a decent design. Sometime back I was reading this book called Practical API design by Jarsalov Tulcach. The author talks about something called as the 'Known Universe.' It refers to how much you know about a problem domain. All our solutions are pretty much going to be based on how much we know about a problem. In software development, if there is anything that is constant, then it must be change. Hence given the fact that your design is going to change anyway, the challenge now lies in making sure how much ready are you in incorporating these changes as your software evolves. The need for refactoring arises from the above truth. Trust me when I say this, no matter how good a design looks today, you will always feel the need to change it, as and when your understanding of the problem domain changes. The smartness lies in adopting the techniques or best practices to shield yourself from having to do too many changes to fit in those new requirements. Hence re-factoring is here to stay. Better get used to it. If there is a need to re-factor your code, don't hesitate to do it. It doesn't indicate that your design is inferior. It just means that the design now needs to accommodate fresh requirements that were not known when the initial design was proposed.

P.S. Feel free to comment on the above points. All the above mentioned points are pretty much the resultant of little exposure that I have to software design. I am yet to learn a lot of things and I am fascinated by the sheer amount of learning that lies ahead of me.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat


Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}