"is a design that is small, efficient and elegant."
"Simplicity is the ultimate sophistication" - Leonardo DaVinci
This is a really difficult one. MinimalDesign is
mostly always in conflict with other principles. We should try and make our design as simple as possible, but simple is almost impossible. However, this design principle must pull on AgileDesign and other principles which can complicate designs. This is a principle to which dues are paid to sanity, realistic expectations and simplicity.
A minimal design:
- Keeps it simple.
- Is one that tries to create a small architectural footprint.
- Abstracted terminology is kept to a minimum.
- Finds the core expression of the solution.
- Avoids mess, clutter and distractions.
- Implementation is minimally categorized.
- Minimal is fine grained. Smallest atom classes, methods.
- Uses other design artifacts (as long as those artifacts maintain the same principles)
Sometimes, simply by implementing something small in our software, we can end up with something than cannot be described as simple. Even the smallest of utilities seems to take 1 to 3 months of development.
So how can you keep things "minimal"?
Intent
Keeping code small, light, fine grained and minimal creates simpler, cleaner code. The intent of this MinimalDesign is promote easier smaller, less complicated thinking, as well as less complicated changes.
Motivation
Code gets complex anyway. Software becomes harder to read and understand. It does this by nature. It will never remain small, so therefore we should fight against it as much as possible. It is like exercise, if you don't you get unfit, if you do you get fit. If you try to create MinimalDesign, you are prolonging the life of the software.
The motivations are actually quite vast, here are a few.
- Your code is large
- It is increasingly taking longer to find and fix.
- You don't want to design something too large or complex
- You have developers who are unsure of the code
- You can't easily tell what impact a change would make.
- You can look and find something to refactor, anywhere in any section of code.
Solution
The solution is to design and implement "minimally" from the outset, and/or continually Design and Refactor to make code minimal. There are many ways you can do this. Think smaller and do not over complicate. A class with one one method is simpler than one with 5 methods, and you have a few ways you can make it more minimal.
Refactoring
You can refactor code so it becomes smaller. You can also hide the scope, make this internal, private, and other means to hide them from callers. You can split and create classes which are not visible to clients and those that are visible, can be made smaller.
Conventions, Standards and Patterns
It is much easier to read complex code, if it contains elements you are familiar with. Having the same variable prefixes, the same standards, you already begin to make things more understandable if you are familiar with the standard.
Collaboration
on objects and even on a method level, to make them more usable for others. Having these software assets as small and granular as possible, requires collaboration in a team, so reuse is greatly enhanced. Tell your team, what reusable methods you have created for them.
Review
Having a person responsible (as often as required) for reviewing code and simplifying, merging and removing complex elements for simpler ones, can help. Often in the middle of a project, its already filled with bits and pieces that need changing. I say set a day or two aside, and do it. Otherwise it will have a much greater negative impact later on.
Focus and streamlined
Having code do precise things, have a class and a method be focused. Make sure it is logical and objects pass in as parameters don't over expose properties you don't need. Make sure there is not two or more of the same thing. Condense, focus and concentrate on making specific code. Tight code that does little, is always better than loose code that does a lot.
One idea
Leading from being focused, you really need to be sure your code, class, module, has the same idea. Consistency of calls, and ideas within classes is important. If you pass a connectionString as a parameter, make sure its always first, or last, not first in one method and second in another function. Don't mix and match ideas.
Refactor until Done
It is important to make code smaller. Make a method smaller. Make a class smaller, by separating it out, splitting it and reworking it.
This used to take a lot of time. But with tools, you can easily refactor 5 methods every day, in between your standard tasks, and not feel it. If the refactoring is taking too long, stop, roll back, and refactor it later, when you have more time. But always thinking about refactoring is very important.
Applicable Patterns
Singleton (GoF)
FactoryMethod (GoF)
ProtoType (GoF)
Facade (GoF)
Adaptor (GoF)
Strategy (GoF)
Template Method (GoF)
Controller (Grasp)
Information Expert (Grasp)
High Cohesion (Grasp)
Simplicity (XP)
Build Feature List (FDD)
Design By Feature (FDD)
ConflictsAgileDesign, ReachableDesign
Ammerse Principles