Share
Embed
It is not SOLID Anymore
* 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?
Lemi Orhan Ergin PRO
November 21, 2020
Transcript
54 slides
-
anymore it's not SOLID Rethinking Software Design and Modularity lemi
orhan ergin co-founder, -
LEMi ORHAN ERGiN co-founder, Craftbase founder, Software Craftsmanship Turkey alumni,
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 -
I know SOLID principles Really? How you apply? S
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. -
Preexisting knowledge impedes one’s ability to reach an optimal solution
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 -
SOLID It seems all convey to "write simple
code" ** Check out Daniel Terhorst-North's deck: h t t ps://speakerdeck.com/tastapod/why-every-element-of-solid-is-wrong -
March of 1995 comp.object mailing list I believe the idea
comes after Object Oriented Construction the following book of Meyer: -
March of 1995 comp.object mailing list Robert Martin sent 11
items via email about „The Ten Commandments of OO Programming‰ https://groups.google.com/d/msg/comp.object/WICPDcXAMG8/EbGa2Vt-7q0J -
Robert Martin sent 11 items via email about „The Ten
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. -
EPENDENCY INVERSION PRINCIPLE INGLE RESPONSIBILITY PRINCIPLE PEN-CLOSED PRINCIPLE ISKOV SUBSTITUTION
PRINCIPLE NTERFACE SEGREGATION PRINCIPLE S O L I D -
Solid is not about good or simple design, it's about
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 -
Solid is about preventing so f t ware from being
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 -
Solid principles are unclear, vague, and open to potentially dangerous
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 ? -
is it about not writing too much code in one
place ? SINGLE RESPONSIBILITY PRINCIPLE SRP -
David L. Parnas, 1972 Encapsulation and Modular Programming On the
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 -
SINGLE RESPONSIBILITY PRINCIPLE SRP 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. -
SINGLE RESPONSIBILITY PRINCIPLE SRP what is responsibility ? from
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 -
SINGLE RESPONSIBILITY PRINCIPLE SRP is all about separation of concerns
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 -
A so f t ware system must be decomposed into
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 -
Code belonging to same concern change together. That's high cohesion.
All the methods and properties should work towards the same goal. Every piece of code has some clear purpose. COHESION -
THE MODULARITY MINDSET SEPARATION OF CONCERNS INFORMATION HIDING INVERSION
OF CONTROL DEPENDENCY INJECTION DEPENDENCY INVERSION COUPLING COHESION wiring direction shape isolation responsibility dependency PRINCIPLE PRINCIPLE PATTERN PRINCIPLE -
SEPARATION OF CONCERNS INFORMATION HIDING INVERSION OF CONTROL DEPENDENCY
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. -
Encapsulation Data encapsulation Information hiding Factory pa t t ern
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. -
SRP Separation of Concerns increase cohesion by separating concerns
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 -
is it about small interfaces on top of huge
codebase ? INTERFACE SEGREGATION PRINCIPLE ISP -
Rober C. Martin, 1996 h t t ps://drive.google.com/file/d/ 0BwhCYaYDn8EgOTViYjJhYzMtMzYxMC0 0MzFjLWJjMzYtOGJiMDc5N2JkYmJi/view
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 -
Clients should not be forced to depend on methods they
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 -
Clients should not be forced to depend on methods they
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 -
Limit coupling surface, minimize number of methods in the contract.
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 -
Interfaces are not the only way to expose as contracts,
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 -
SRP Separation of Concerns increase cohesion by separating concerns
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 -
is it about subtypes that I've never used ?
LISKOV SUBSTITUTION PRINCIPLE LSP -
Barbara Liskov, 1987 Usefulness of Hierarchy in Program Development
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 -
LISKOV SUBSTITUTION PRINCIPLE LSP If an object y has all
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. -
If an object y has all 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. 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 ? -
A class should do what it sounds like it does.
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 -
Interchangeability is about sub-typing. All implementations of interfaces are subtypes
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. -
Abstraction is about handling complexity by hiding unnecessary details from
the user Abstraction Parameterized system design Indirection Rule based design Polymorphism Composition, Inheritance Information hiding Layered architecture Ports and adapters -
SRP Separation of Concerns increase cohesion by separating concerns
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 -
DEPENDENCY INVERSION PRINCIPLE DIP Rober C. Martin, 1994 h t
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 -
DEPENDENCY INVERSION PRINCIPLE DIP High-level modules should not depend on
low-level modules. Abstractions should not depend on details Details should depend on abstractions. -
DEPENDENCY INVERSION PRINCIPLE DIP High-level modules should not depend on
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 -
DEPENDENCY INVERSION PRINCIPLE DIP Abstractions should not depend on details.
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 -
DEPENDENCY INVERSION PRINCIPLE DIP cache interface cache implementation business object
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 -
DIP is about making the business independent of external systems.
Decouple your behavioral models from your data models. DIP decouples the construction of an object from its use. DEPENDENCY INVERSION PRINCIPLE DIP -
SRP Separation of Concerns increase cohesion by separating concerns
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 -
OPEN CLOSED PRINCIPLE OCP am I not allowed to change
existing code anymore ? -
OPEN CLOSED PRINCIPLE OCP Bertrand Mayer, 1988 Open-Closed Principle h
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 -
OPEN CLOSED PRINCIPLE OCP So f t ware entities should
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. -
OPEN CLOSED PRINCIPLE OCP So f t ware entities should
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 CLOSED PRINCIPLE OCP Modules (possible to expand) should be
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. -
Expose potential extension points. For protection against change to
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 -
SRP Separation of Concerns increase cohesion by separating concerns
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 -
lemi orhan ergin co-founder, speakerdeck.com/lemiorhan Separation of Concerns Information Hiding
Inversion of Control Dependency Injection Dependency Inversion Maintainability, Flexibility Ports and Adapters Hexagonal Architecture Testing in Hexagonal Arch. How TDD Evolves Code Modular Monoliths SOLID Actually Means Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle