How to design software
A few months back, while I was exploring the internet, trying to debunk my negative outlook of “there are no good SOLID principle blogs out there” - I somehow stumbled upon a couple of Quora posts. In these posts, a bunch of users explained their frustrations in designing an application and, from what I can recall, implementing SOLID principles.
Most of the users seemed to assume they were just bad at planning, which was heartwarming to see - since most of them had PhDs by the time I found their posts. The thing is, when it comes to planning, there are so many ways you can go wrong - that you should pretty much feel like an idiot when you give it a shot.
I’m in my third year of being a Software Developer and have, for most of my time being a developer, always strived to improve the quality of my work. While I still have a long way to go, I feel I have gotten into a decent workflow of how to plan out an application top-down.
So for what its worth, here is what I’ve learned in my attempts at software design.
LESSON 1: DON’T PANIC
One of the most frequent complaints were complaints about plans not entirely working out like the developer wanted them to. This should always be expected when executing any type of plan when it comes to designing and building an application. In development, just like in all other endeavors in life, failure is par for the course.
The main solution to this is to keep going back to the drawing board. Programming languages can be hard to conceptualize for beginners. Even if you’ve been coding for a year, if you haven’t planned before - it becomes disturbingly clear how many blind spots there is in your understanding of how code runs. OOP languages, supposedly made with the aim to be easier to conceptualize, I would say are even harder to conceptualize, just because there are so many more restrictions required to make them work - than there are with procedural languages.
So long story short, there’s no easy way to get better, the only way is to fail and fail frequently.
LESSON 2: DON’T REINVENT THE WHEEL
When I first decided to start designing my applications, I thought that I could invent my own smart little Design Patterns and I could deduce the best approach to software design, simply by trial and error. I could’ve done that too, the problem is just that if you don’t learn the existing ones - you’ll continually reinvent the existing ones. Naturally, there will always be new discoveries to be made in programming - but discoveries take time and patience. Best to rather master the existing techniques and hope that that will lead you on your path to new discoveries.
So where do you start? Well..
UML Class Diagrams: There are various ways to design a system: Sequence Diagrams, User Stories, State Machines, etc. For me, although the mentioned ones can be great supplementary design tools, you can never go wrong with class diagrams. If you’ve got a technical mind, you probably already have a good mental image of how the system will work, class diagrams merely help you identify your mental errors before you get to the actual coding.
Probably the most well-defined instructions for writing and designing complex applications. If you take care to truly understand each principle, you’ll understand the weight they hold in optimizing the development and maintenance of applications. Principles like DRY, YAGNI and KISS you’ll discover yourself by a year of coding - discovering SOLID principles take a lifetime.
The exact ones I can’t recommend, I would rather say understand most of the widely used ones and then only practice them when it seems appropriate. I would say identifying when they’re appropriate, is probably the hardest part. Even when your judgment is bad though, you’ll still learn a lot out of trying to implementing them.
Refactor Guru is my go-to site for a comprehensive list and explanation of the most important ones: https://refactoring.guru/design-patterns
This is more for those who actually have the authority to implement the SCRUM system, as most who read this probably won’t. But I’d say that even if you don’t, at least try and convince your team to think it over. I’ve been in teams where no retrospectives or sprints are carried out and the difference is night and day.
LESSON 3: PRACTICE TDD
Writing tests might seem completely irrelevant to design, but tests actually do a big part in maturing your designs. If you’re following the three laws of TDD, that is...
You are not allowed to write any production code unless it is to make a failing unit test pass. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
… you can’t write OOP applications without at least implementing the Dependency Inversion Principle and the Open/Closed Principle. These tests will then not only clear your application of most bugs but also provide a quality assurance check - making sure you understand the design principles you’re trying to implement.
Every software developer goes through growing pains, I’m still going through mine. Although there are general issues and solutions that have been identified by the developers that have come before us, some solutions can’t be taught and can only be learned through the heavy burden of experience.
Published By: Duen Oosthuizen