2021-11-24

Principles of Software Engineering Design for Non-Engineers.

header-image

It is common for business stakeholders  to equate design with user interface or  user experience. Although this is of fundamental importance in most user facing software products, and has gained exponential significance, design in software engineering goes much deeper than the user experience, it  is about the full extent of a software application, from front end to back end, and the connections with the outside world. They are not unrelated: a correct design will at the end of the day define project success and ultimately empower the user experience.

Why is it important to you ?
As the sponsor, owner or business stakeholder of a software development project you should have a high level understanding of what represents a good software design. Understanding what that represents, why it is important and the impact that negative design has on your project. Having that understanding will make you more aware and knowledgeable of  challenges, weaknesses and opportunities.

But, what does good design mean for software developers? Is it the number of inputs and outputs, the number of lines of code, names of variables?  Although there are good practices to guide these metrics, there are other major fundamentals that ALL developers should be following at every step. For the most part, it is in their DNA, and experienced developers will work with these concepts, without even thinking about it. Although sometimes , and for different reasons, that is not the case.

Modularization

Modularization is at the heart of design in software engineering. We will see what are the benefits of a correct modular design, but before I would like to present these fundamentals that lead to a correct modularization.

In the late 60’s  Larry Constantine developed the concepts of cohesion and coupling  This was in the midst of the first methodology, Structured Analysis and Design, that was prevalent throughout the 70s and 80s.

Cohesion

Represents how focused and self contained a module is. That it’s purpose is clear, preferably unique, and everything it needs to perform its task is performed with minimal dependency on other modules within the system.  More cohesion is better.

cohesion

Coupling

Represents how much a software module depends on other modules. Any changes in one module will impact the other modules behaviour in unplanned ways.  Loose ( less )  coupling is better.  The image shows a system where there is only 1 connection between different modules. This would be a loosly coupled design.

Coupling

Good system design will be composed of modules that have strong cohesion and weak coupling. Of course, there are degrees of both characteristics. It is not a black / white situation. In the image below, each component ( A,B,C) makes has only 1 path of communication with the other components. Most of it's execution is performed witthin the component itself.

Good modularization

If you’re intereted in more detailed explanation regarding these 2 fundamentals, there is plenty of information on the web, here are a couple of links :

https://courses.cs.washington.edu/courses/cse403/96sp/coupling-cohesion

https://www.coursera.org/lecture/object-oriented-design/1-3-1-coupling-and-cohesion-q8wGt.

Encapsulation
Based on the 2 fundamentals we have just seen and born in the context of Object Oriented Programming. Encapsulation means that a Module or Object hides it’s inner workings. It has clear interfaces that the outside world uses to communicate and/or request things from the object. You don’t know exactly how or what is going on inside, you know what you need to ask/give and what answer / result you will obtain.

Amongst other benefits, this prevents changes in one area to trivially break functionality in another area.

Benefits of Modular Design

With those 3 important fundamentals, guiding the development team in building their components, our software product or application with a good modular design will be easy to :

  1. Understand: A well-modularized system is much easier to reason about, think about and communicate to others.
  2. Improve: Well design modules maximizes your ability to fix or improve individual module implementations without needing to update any other, dependent modules.
  3. Refactor: The less inter-dependencies in a project, the easier it is to make large changes across multiple modules.
  4. Reuse: Modules with the best-conceived purposes are fully reusable. Whenever you have the same problem again, you can simply reuse the old solution.
  5. Test: Modules with good interfaces and minimal inter-dependencies are easier to test. Scalability: All of which adds up to the most important benefit of modules: They let our applications scale. It’s impossible to build large applications without good modularization. Without modules, complexity will destroy your productivity.

Most recently there are other principles, which are further elaborations of these 3

In his definition of XP programming, Kent Beck  defined a very basic set of principles that should guide developers in creating well designed software :

In his book Extreme Programming, Embrace change,  Beck states

  • Runs all the tests
  • Has no duplicated logic. Be wary of hidden duplication like parallel class hierarchies
  • States every intention important to the programmer
  • Has the fewest possible classes and methods

If you’re interested you can get some further reading at

https://medium.com/swlh/clean-code-4-rules-of-simple-design-f86b066ee43d

Some of the other well known principles in the software development community are :

KISS

The KISS principle was coined by Kelly Johnson, and it states that most systems work best if they are kept simple rather than making them complex; therefore, simplicity should be a key goal in design and unnecessary complexity should be avoided.

DRY

Don’t Repeat Yourself” – How many times do you see that there are similar codes in different parts of a system? The DRY principle, formulated by Andrew Hunt and David Thomas in their book The Pragmatic Programmer, states that “every piece of knowledge must have a single, unambiguous, authoritative representation within a system."  In other words, you must try to maintain the behavior of a functionality of the system in a single piece of code.

What does that mean to you ?
As an executive sponsor or a project manager you may run into situations that require improvements on the development team or process.

  • Are issues taking too long to develop ?
  • Simple changes or extensions of functionality are becoming very costly to implement ?
  • A change in one place, raise unexpected bugs somewhere else 
  • Developers seem to be focused on the same issue for more than a couple of days ?
  • Too much functionality being built in the same modules ?
  • Code duplicated in different places ?
  • Changes in one module, demand changes in others ?

Questioning is healthy

As a true Agilist , it is important that you TRUST your team , their objectivity and criteria to know how to make the necessary changes in course or practice. It is beneficial to the project’s health that you have the ability to question and have a high level understanding of these principles. If  you are working closer to the backlog, you can see if the decomposition of issues or stories seems to reflect a design mentality and even better, a correct design. A correct modularization can be perfectly mapped as deliverables in a project management tool.