* Why do we misunderstand SOLID Principles?
* Is SOLID too object oriented concept?
* Is SOLID a nonsense, or the principles we really need?
* We use a dynamic language. Is SOLID still valid?
* What are the roots of principles we usually miss?
Sony, eBay, ACM, iyzico programming, since 2001 with love practitioner, modular design for years speakerdeck.com/lemiorhan this one are right there! I am an active programmer I am usually in that mood the others happen when I run out of coffee mainly on backend side
for Single responsibility. I forgot the others. Of course we know SOLID. We think we use it all the time while coding and during code reviews. And of course it is a good thing. I've never heard the opposite.
Every a t t empt referring to past solutions adds a new bracket to the wall of illusion of competence Agile, Devops, Clean Coding, SOLID, else? THE EINSTELLUNG EFFECT means mindset, attitude you past experience gives strong opinion about what it really is
Commandments of OO Programming‰ https://groups.google.com/d/msg/comp.object/WICPDcXAMG8/EbGa2Vt-7q0J The theory was introduced by Robert Martin in his paper "Design Principles and Design Pa t t erns" in 2000. SOLID acronym was introduced in 2004 by Michael Feathers. But as so f t ware development evolves, the principles should change its shape while preserving their roots.
be t t er design. Solid is not about understanding OOP be t t er, it is about understanding the code (i.e. the design) be t t er. Solid is not the goal, it is a tool, a guideline for using while refactoring so f t ware into a be t t er design. IS NOT ABOUT... SOLID
rot from uncontrolled dependencies by separating concerns. Solid is about writing code that not only allows change, but we have to write code that expects change. Solid is about limiting the impact of change by making the code easy to change and keeping it backward compatible. IS ABOUT MANAGING DEPENDENCIES SOLID
interpretations. Solid is helpful and important. However even senior developers cannot understand and handle them well. Principles should be clarified and rephrased to eliminate misunderstandings and misinterpretations. IS DANGEROUS! SOLID really ? isn't "having fewer classes and making all singleton" solid ?
Criteria To Be Used in Decomposing Systems into Modules Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design h t t ps://www.amazon.com/Structured- Design-Fundamentals-Discipline- Computer/dp/0138544719 h t t ps://www.win.tue.nl/~wstomv/edu/ 2ip30/references/ criteria_for_modularization.pdf Larry Constantine, Edward Yourdon, 1979 Cohesion Agile So f t ware Development, Principles, Pa t t erns, and Practices Robert C. Martin, 2003 Single Responsibility Principle h t t ps://www.amazon.com/So f t ware- Development-Principles-Pa t t erns- Practices/dp/0135974445 Domain-Driven Design: Tackling Complexity in the Heart of So f t ware Eric Evans, 2004 Aggregates h t t ps://www.amazon.com/Domain- Driven-Design-Tackling-Complexity- So f t ware/dp/0321125215 SINGLE RESPONSIBILITY PRINCIPLE SRP
one single responsibility. There should never be more than one reason to change. A component should do only one thing, and do it right. This principle is about people.
what perspective ? many small classes ? you mean "high cohesion" ? what about fixing bugs and adding features ? what about cross cutting concerns ? converters ? facades ? patterns ? that's not always true A class should only have a one single responsibility. There should never be more than one reason to change. A component should do only one thing, and do it right. This principle is about people. multi layered architecture is not about SRP Programmers stated that needs clarifications
and cohesion. A component should belong to one concern based on business responsibilities. Without context, every module can violate SPR to some extend. There is no such a thing as "do one thing". There exists di f f erent levels of cohesion. SRP
parts that overlap in functionality as li t t le as possible. SEPARATION OF CONCERNS Make sure not mixing di f f erent dimensions, concepts together. Edsger W. Dijkstra coined the term to describe the mentality behind modularization, which allows the programmer to reduce the complexity of the system being designed. a set of information that affects the code of a computer program
INJECTION DEPENDENCY INVERSION COUPLING COHESION wiring direction shape isolation responsibility dependency PRINCIPLE PRINCIPLE PATTERN PRINCIPLE SRP is just a practical consequence of fundamental programming principles, it’s not a goal by itself.
Extract to method or class Composition over Inheritance Domain driven design Primitive obsession & DRY Information expert principle Keep what varies together, like division of labor in an organization. Encapsulation protects the entities it protects from inconsistency. It's not about hiding complexity, it's about having a fail-safe mechanism.
based on business level responsibilities Abstraction Encapsulation Data encapsulation Information hiding Layered architecture Extract to method or class Parameterized system design Indirection Rule based design Polymorphism Cohesion Coupling techniques SOLID PRINCIPLES INTERACTION DIAGRAM Composition, Inheritance Information hiding Layered architecture Ports and adapters Composition, Inheritance Domain driven design Primitive obsession & DRY Information expert principle
INTERFACE SEGREGATION PRINCIPLE ISP Engineering Notebook column for The C++ Report, Object Mentor While consulting Xerox, Robert Martin noticed that as the so f t ware grew, making modifications became more and more di f f icult so that even the smallest change would take a redeployment cycle of an hour, which made development nearly impossible. The design problem was that a single Job class was used by almost all of the tasks. Whenever a print job or a stapling job needed to be performed, a call was made to the Job class. This resulted in a fat class with multitudes of methods specific to a variety of di f f erent clients. Because of this design, a staple job would know about all the methods of the print job, even though there was no use for them. He applied to the Xerox so f t ware, an interface layer between the Job class and its clients was added using the Dependency Inversion Principle. Instead of having one large Job class, a Staple Job interface or a Print Job interface was created that would be used by the Staple or Print classes, respectively, calling methods of the Job class. Therefore, one interface was created for each job type, which was all implemented by the Job class. h t t ps://en.wikipedia.org/wiki/Interface_segregation_principle
do not use. Many client specific interfaces are be t t er than one general purpose interface. Interfaces should be small. INTERFACE SEGREGATION PRINCIPLE ISP
do not use. Many client specific interfaces are be t t er than one general purpose interface. Interfaces should be small. Programmers stated that needs clarifications is having interfaces a must ? should every class have an interface ? interface soup ? single method interfaces ? then aggregate again ? INTERFACE SEGREGATION PRINCIPLE ISP
Keep abstractions highly cohesive so that users don’t end up depending on things they don’t need. Avoid depending on things that you do not use. ISP is a poor guidance when designing so f t ware, but an excellent indicator of whether it’s healthy or not. INTERFACE SEGREGATION PRINCIPLE ISP
we have duck typing for dynamic languages. Any public method is also a contract to its customer. Composition over inheritance is a way to eliminate unnecessary unused dependencies. Ask, what's the least amount of information each abstraction requires? Make sure you expose or make public only the methods you really need. Do not use boolean/null parameters for enabling/disabling business logic. INTERFACE SEGREGATION PRINCIPLE ISP
based on business level responsibilities Cohesion Coupling Abstraction Encapsulation Data encapsulation Information hiding Layered architecture Extract to method or class Parameterized system design Indirection Rule based design Polymorphism ISP Limit Coupling Surface increase cohesion by not depending things we don't use techniques SOLID PRINCIPLES INTERACTION DIAGRAM Composition, Inheritance Information hiding Layered architecture Ports and adapters Composition, Inheritance Domain driven design Primitive obsession & DRY Information expert principle
Data Abstraction and Hierarchy h t t ps://dl.acm.org/doi/ 10.1145/62139.62141 Barbara Liskov, Jeane t t e Wing, 1994 Behavioral Subtyping h t t ps://www.cs.cmu.edu/~wing/ publications/LiskovWing94.pdf LISKOV SUBSTITUTION PRINCIPLE LSP A Behavioral Notion of Subtyping Applying "Design by Contract" Bertrand Meyer, 1992 Design By Contract h t t p://se.ethz.ch/~meyer/publications/ computer/contract.pdf
the properties of object x, then we can safely use y anywhere we use x and that y is a subtype of x. If y does not have all the properties of x, it is not a subtype of x. Every derived class should be substitutable for their base class.
x, then we can safely use y anywhere we use x and that y is a subtype of x. If y does not have all the properties of x, it is not a subtype of x. Every derived class should be substitutable for their base class. isn't it all OOP related ? what if we do not use subtypes at all ? Programmers stated that needs clarifications LISKOV SUBSTITUTION PRINCIPLE LSP is inheritance a must ?
Any behavioral change breaking this that should be a di f f erent dependency. LSP is not about inheritance, it is about behaviour of code units. Build so f t ware systems from interchangeable parts, those parts must adhere to a contract that allows those parts to be substituted one for another. LISKOV SUBSTITUTION PRINCIPLE LSP
of an interface. All duck-types are subtypes of an implied interface. Every user of the base interface, whether declared or implied, must agree on the meaning of that interface. LISKOV SUBSTITUTION PRINCIPLE LSP A duck should look like a duck, swim like a duck, and quack like a duck. Otherwise it's not really a duck.
the user Abstraction Parameterized system design Indirection Rule based design Polymorphism Composition, Inheritance Information hiding Layered architecture Ports and adapters
based on business level responsibilities ISP Limit Coupling Surface increase cohesion by not depending things we don't use decrease coupling by interchangeable parts Inter changeability LSP Abstraction Encapsulation Composition, Inheritance Information hiding Layered architecture Ports and adapters Data encapsulation Information hiding Layered architecture Extract to method or class Parameterized system design Indirection Rule based design Polymorphism Composition, Inheritance Domain driven design Primitive obsession & DRY Information expert principle Cohesion Coupling techniques SOLID PRINCIPLES INTERACTION DIAGRAM
t ps://linux.ime.usp.br/~joaomm/ mac499/arquivos/referencias/ oodmetrics.pdf OO Design Quality Metrics: An Analysis of Dependencies Agile So f t ware Development, Principles, Pa t t erns, and Practices Robert C. Martin, 2003 Dependency Inversion Principle h t t ps://www.amazon.com/So f t ware- Development-Principles-Pa t t erns- Practices/dp/0135974445
low-level modules. from code that is stable separate code that changes frequently business code domain logic integration code client specific code framework dependent code delay technological decisions immune to technical evolution test domain in isolation knows about needs
Details should depend on abstractions. interfaces ports implementations adapters the depending class has no knowledge about the concrete class that it is going to use
uses domain, business code code we really care about changes o f t en integrations, infra code write once and forget hard to change HIGH LEVEL MODULE LOW LEVEL MODULE framework layer or a main component responsible for constructing objects and injecting them MAIN COMPONENT
based on business level responsibilities ISP Limit Coupling Surface increase cohesion by not depending things we don't use decrease coupling by interchangeable parts Inter changeability LSP DIP decrease coupling by depending to abstractions enabling modular design Business Independence Abstraction Encapsulation Data encapsulation Information hiding Layered architecture Extract to method or class Parameterized system design Indirection Rule based design Polymorphism Cohesion Coupling techniques SOLID PRINCIPLES INTERACTION DIAGRAM Composition, Inheritance Information hiding Layered architecture Ports and adapters Composition, Inheritance Domain driven design Primitive obsession & DRY Information expert principle
t t ps://www.amazon.com/Object- Oriented-So f t ware-Construction-Book- CD-ROM/dp/0136291554 Object-Oriented So f t ware Construction Pa t t ern Languages of Program Design, Vol 2 > Prioritizing Forces Alistair Cockburn, 1996 Protected Variation h t t ps://www.amazon.com/So f t ware- Development-Principles-Pa t t erns- Practices/dp/0135974445 David L. Parnas, 1972 Information Hiding On the Criteria To Be Used in Decomposing Systems into Modules h t t ps://www.win.tue.nl/~wstomv/edu/ 2ip30/references/ criteria_for_modularization.pdf Craig Larman, 2001 Protected Variation h t t ps://martinfowler.com/ ieeeSo f t ware/protectedVariation.pdf Protected Variation: The Importance of Being Closed
be open for extension, but closed for modification. Developers must support new functionality without editing the source code of the existing modules. The source code of such a [class] is inviolate. No one is allowed to make source code changes to it. You can use interfaces as extension points to make your code truly adaptable.
be open for extension, but closed for modification. Developers must support new functionality without editing the source code of the existing modules. The source code of such a [class] is inviolate. No one is allowed to make source code changes to it. You can use interfaces as extension points to make your code truly adaptable. Programmers stated that needs clarifications source code can’t be changed ? who can write perfect code ? abuse of inheritance ? change requires refactoring
open for extension and adaptation. Modules (the ones available for use by other modules) should be closed to avoid modification that a f f ect backward compatibility. It doesn't mean you should not change the code. Preferably add code more than change while adding new features. We should avoid compatibility breaking changes to existing code, changes that could result in bugs or other kinds of regression. Abstraction is the key. Inheritance is not the only way to decouple modules.
the existing code, identify points of evolution points, create a stable interface around them. We need just enough adaptability. You should be explicit in what you allow and disallow to be extended. Data Encapsulation Interfaces Polymorphism Indirection Uniform Access Data driven design Parameterized design Interpreter driven design Rule based design Re f l ection Object purism PROTECTED VARIATION PRINCIPLE ROOT OF ALL PATTERNS OPEN CLOSED PRINCIPLE OCP information hiding, PV and OCP are all same principle with a different name and view
based on business level responsibilities ISP Limit Coupling Surface increase cohesion by not depending things we don't use decrease coupling by interchangeable parts Inter changeability LSP DIP decrease coupling by depending to abstractions enabling modular design Business Independence OCP Protected Variation increase cohesion while growing codebase decrease coupling while growing codebase Abstraction Encapsulation Data encapsulation Information hiding Layered architecture Extract to method or class Parameterized system design Indirection Rule based design Polymorphism Cohesion Coupling techniques Cohesion and coupling are inter-connected with each other and cannot be totally separated. However in order to give the idea of the way of how concepts relate, we separate by their impact on explanation. SOLID PRINCIPLES INTERACTION DIAGRAM diagram prepared by Lemi Orhan Ergin, @lemiorhan, 11.2020 Composition, Inheritance Information hiding Layered architecture Ports and adapters Composition, Inheritance Domain driven design Primitive obsession & DRY Information expert principle