When I was a novice programmer, I was interested in intricate designs, I believed if there is not a dozen of “Interfaces” either “Abstract classes” the design is not mature, I believed there are always many changes out of the door waiting for tackle the project. The result was a super complex design which tried to defend against all changes in the world, even climate change! Many of those changes never occurred.
Today after more than 15 years of working in this field I have found out many of changes are just living in our imagination which may results in a design with massive needless complexity, a toxic complexity. The real world including human interactions, businesses, economic relations, are complex intrinsically and base on “Miller’s article” we know the humankind cannot handle more than 7+-2 complexity in his brain simultaneously; What do we retain by adding more complexity to the reality in the form of needless complexity? We make software for managing a part of this complexity. As a solution I have established a manifesto for object-oriented design for myself and my students to mitigate this risk, in the following paragraphs I describe it.
As we all know, the central pillar of object-oriented mindset is divide and conquer and keeping data and their related operation in the same place as a “Class” at the same time. Object-oriented paradigm starts with four main Principle; they are” Abstraction, Modularity, Encapsulation and Hierarchy” –“AMEH” as their abbreviation, the word “AMEH” in Persian means “Aunt” so as a Persian programmer if you forget the main principles just think about your “AMEH”. As “Craig Larman” has said in his seminal book “Apply UML and Patterns”, there are three levels of design in an object-oriented design process, “Conceptual, Specification and Implementation” design.
The first one -the conceptual design- is the result of applying “AMEH” Principles on the real world concepts to remove those data elements of the real-world concepts or objects which have no use in solving the problem in hand. This process is based on a simple fact “if you don’t need data for answering a question, just skip it. You can infer this from your requirements in addition to your solution” For example when you are creating an invoicing system for a small retailer “What do you need to keep as customer information?” Do you need her nationality or her Grandmom’s name? “I suppose the answer is NO”. This data omitting was done based on “A” from “AMEH”, I mean Abstraction. Then you start pruning the relationships between the objects to divide the concept to conquer the complexity which can be emerged from a mesh relation graph between concepts and objects. “Encapsulation and Modularity” help in the same way. For sum up, in the first step of the design, you make the word simpler than it is, to be not only understandable but also manageable.
Specification design is the second step toward an object-oriented design, it is the result of responsibility (Operations) assignment to the objects from the previous step. GRASP (General Responsibility Assignment Software Principles) besides S.O.L.I.D Principles guide you during a wise decision-making process. The result is a simpler model than the conceptual model.
Although you can convert Specification design to executable code by all object-oriented languages, this is not the simplest model of solution you can have. Here the technology and built-in capabilities’ of the languages and frameworks come in, they help to convert the Specification design into a more understandable model than it is. For example, the result of the Specification design has an “Observer Design Pattern” and you are using C#.Net as the programming language, should you keep the “ISubject / IObserver” interfaces? Of course NO! Because there is a simple solution in C# for this type of problems, “The delegates and Events”. So thanks to the technology this level of design is more straightforward than its ancestors. Finally, you have a design which does not resemble the real world problem domain but it can solve a specific problem there with no useless abstraction, interfaces and over design.
As the bottom line, a good object-oriented design is royal to its paradigm pillars and principles while protecting the central part of the design against real changes, not imaginary changes. The result of a good design is more straightforward and smaller than the source of the problem in the real world. So Please KISS it!
PS: 1- “In another article, I will talk about some measurement to find out which part of a design is the most essential part of it which should be protected against changes.
2- KISS= Keep it Stupidly Simple.