Modular design concepts: Simple vs. easy
Simple and easy are often believed to be the same, but in software development they can be false friends. How to distinguish between them is one of the basic problems of modular design. Let's delve deeper into this topic.
Table of content
- How do we understand “simple”?
- How do we understand “easy”?
- Simple vs. easy
- Examples of “simple” in programming
- Examples of “complex” in programming
- How to determine whether your code is simple?
- Ways to make code simpler
- Simple vs. easy in modular deisgn. A summary
In the second part of my modular design article series, I’m going to draw the line between “simple” and “easy”. How do they differ from each other? What do they mean for a programmer? Let’s find out!
How do we understand “simple”?
The first connotations of the word “simple” that come to my head are:
- uncomplicated,
- atomic, in the sense that it cannot be divided into smaller parts,
- can build complex things,
- can be easy to use,
- can be hard to use,
- can be measured or counted, e.g. number of parts and/or dependencies
- examples: a wheel, a bicycle (?)
How do we understand “easy”?
- unchallenging,
- effortless,
- easiness is impossible to measure,
- subjective, i.e. flying an airplane can be easy for a pilot with 20 years of experience, but not for me.
Simple vs. Easy- easy or hard most often refer to the use of an object,
- simple and complex refer to the level of sophistication or intricacy.
Having explained the above, we arrive at the concept of true simplicity. True simplicity means - here’s the tricky part - ease of understanding, changing or debugging.
Complex things can be made simple, be it by disentangling, refactoring, or redesigning.
Same as hard things can be made easy through learning, experimenting, or by trying.
Simple vs Easy study: Libraries
What about a case in which something can be easy, hard, simple, and complex at the same time? Let’s consider the example of something most web developers are familiar with: libraries.
Take the popular saying “there’s a gem for that”. Rails developers know it perfectly. If you are not writing code in Ruby on Rails, let me clarify this one can be translated into “There is a solution (i.e. a library, “gem”) to this kind of complex problem”.
Libraries can make our code more complex - e.g. (by adding extra dependency or by forcing us to use big interface) yet they make it easier to deliver.
Should devs use Rails gems?
On one hand, completely avoiding them would be equal to reinventing the wheel. Building the entire web application on your own, piece by piece, line by line, when there surely is a ready solution to a particular problem already written by someone else.
On the other hand, relying only on libraries will make you what I call a “stackoverflow” developer, i.e. a person who does not author a single line of code and delivers an application based on ready-made solutions.
That’s why it’s crucial to find a middle ground between those.
Examples of “simple” in programming
- information,
- values,
- functions,
- data,
- rules,
- query languages
Examples of “complex” in programming
- state,
- objects (you have to think about what methods to call on a particular object)
- object-relational mappers
How to determine whether your code is simple?
To come up with an answer, let us answer 3 questions.
- How easy is it to change the business behavior of what we created?
If it’s easy, there are reasons to assume that code is simple. But not always.
- How easy it is to add another rule, condition, or enhance the way our program works?
- Is there a limit to modifications?
If it’s impossible to modify, the code is probably not simple. No matter how easy it was to write this code, it can still be complicated code.
If otherwise, there are grounds to presume that the code is simple.
(This is not enough to fully estimate how complex is our code - this will come with experience)
Ways to make code simpler
The main way is to turn loops, which are very complex constructs themselves, into something simpler and easy to learn.
It can be achieved with 3 functions:
- map,
- filter,
- reduce.
The tricky part is that achieving code simplicity may require coding more stuff on your own.
But as Leonardo DaVinci once put it, simplicity is the ultimate sophistication.
Wondering if it’s true? Think of industries such as design or arts with the strongest emphasis on music: writing a simple, well-arranged tune may require hours of rehearsing, erring, cutting, and refining ideas. That’s also the general tendency I sense in today’s world as such.
Summary
Simple and easy are never the same things.
Same as “complicated” does not always equal “difficult”.
Difficult may turn easy thanks to learning.
Complicated can be made simple through refactoring.
In the realm of programming, I believe that it’s always good to care about your code’s simplicity, even if it is not always easy to write.
This theoretical post was inspired by “The Philosophy of Software Design” by John Ousterhout, which I strongly recommend to anyone of you. The book is language-agnostic, which means you can learn its concepts regardless of the technology you use in your work.
Enjoy!