issues
search
jimin-kiim
/
Software-Engineering
0
stars
0
forks
source link
SOLID
#10
Closed
jimin-kiim
closed
1 year ago
jimin-kiim
commented
1 year ago
Design Smells
SOLID
SRP, OCP, LIP, ISP, DIP
jimin-kiim
commented
1 year ago
Design Smells
Rigidity
the system is hard to chance. bc every time a thing is changed, something else should be also changed. propagation of change
Fragility
a change to one part of the system causes break in many other, completely unrelated parts.
Immobility
hard to disentangle the system into components that can be reused in other systems.
Viscosity
easier to add a hack than to add code that fits into the design
Needless Complexity
there are lots of very clear code structures that aren't actually necessary right now
Needless Repetition
too many cut and paste
Opacity
elucidation of the originator's intent presents certain difficulties related to convolution of expression. too hard to understand
Introduction
Design smells result from mismanaged dependencies
mismanaged dependencies : tangled mass of couplings. (spaghetti code)
OO languages provide tools to help managing dependecies
Interfaces, Polymorphism, lots of power to shape the dependencies
shaping the dependency
SOLID principles
GRASP patterns
"Program to interfaces, not implementations"
"Favor object composition over class inheritances"
"Encapsulate what varies"
...
jimin-kiim
commented
1 year ago
SOLID
R.C. Martin’s Software design principles (SOLID)
SRP, OCP, LIP, ISP, DIP
Single-Responsibility Principle (SRP) 단일 책임의 원칙
Open-Closed Principle (OCP) 개방 폐쇄의 원칙
Liskov Substitution Principle (LSP) 리스코프 치환 원칙
Interface Segregation Principle (ISP) 인터페이스 분리의 원칙
Dependency Inversion Principle (DIP) 의존성 역전 원칙
jimin-kiim
commented
1 year ago
SRP
single responsibility principle
"just because you can doesn't mean you should"
a class might handle a lot of responsibilities but it's not always optimal to have all of them
responsibility: a reason to change the class.
more responsibilities -> more likelihood of change
the more a class changes -> the more likely we will introduce bugs
change can impact others
SRP: separating coupled responsibilities into separate classes
related measure: Cohesion (how strongly-related and focused are the various responsibilities of a module)
Identifying Responsibilities can be tricky
the concept and bound of responsibility depend on how the application is changing.
beware of avoiding needless complexity
if there's no symptom to be changed, it's useless to apply SRP
jimin-kiim
commented
1 year ago
OCP
Open-Closed Principle
"Open Chest Surgery is not needed when putting on a coat"
"software entities should be open for extension but closed for modification"
its behavior should be able to extended without modifying it
open for extension: when we add the functions to the module,
closed for modification: it doesn't result in excessive modification
if violated, design smell of rigidity occurs
example
Rigidity
adding new employee type requires significant changes
Fragile
many switch/case or if/else statements -> hard to find and understand the bugs
Immobile
copy and pasted but what if we need just Faculty and Staff only. we should erase some part of it.
Abstraction is the Key
Abstractions: fixed and yet represent an unbounded group of possible behaviors
"Program to interfaces(or abstract classes) not to implementation (concrete classes)"
guess the most likely kinds of changes and then construct abstractions to protect from the changes.
but beware of considering the cost.
abstractions also increase the complexity so conforming to OCP is expensive.
so do not put hooks in for changes that might happen
initially, write the code expecting not to be changed.
when a change occurs, implement the abstractions that protect from future changes of that kind.
to do it better, use TDD and listen to the tests.
jimin-kiim
commented
1 year ago
LSP
Liskov Substitution Principle
"if it looks like a duck. quacks like a duck. but needs batteries, you probably have the wrong abstraction"
"Subtypes(derived classes) must be substitutable for their bases"
a rule used to check whether to use inheritance or not.
If C is a subtype of P, then objects of type P may be replaced with objects of type C without altering any of the desirable properties of the program
Subtyping and Implementation Inheritance
Subtyping
establishing is-a relationship
aka. interface inheritance
Implementation Inheritance
establishes no semantic relationship
only reuses implementation and establishes syntactic relationship
aka. code inheritance
example
if we want to reuse the implementation of List to make Queue,
we had better exploit object composition, not inheritance
if Queue inherits List, it violates LSP
Queue object cannot be substitutable for List.
bc Queue is more restrictive than List
jimin-kiim
commented
1 year ago
ISP
Interface Segregation Principle
"clients should not be forced to depend on methods they do not use"
"make fine grained interfaces that are client specific"
fat interface:
bundling functions for different clients into one interface. (non-cohesive interface)
-> unnecessary coupling among the clients.
-> break the interface into cohesive groups
reduce recompiling and redeploying of the APIs
protects the user from changes in methods that don't concern it
jimin-kiim
commented
1 year ago
DIP
Dependency Inversion Principle
"would you solder a lamp directly to the electrical wiring in a wall?"
"high level modules should not depend on low level modules. both should depend on abstractions"
"abstractions should not depend on details. details should depend on abstractions"
why inversion
bc DIP attempts to invert the dependencies that result from a structured analysis and design approach
Structured Anlaysis and Design; Program > Module > Function
DIP; Program > Interface, Module > Interface
it also inverts the ownership not only the dependency
typically; a service interface is 'owned' or declared by the server.
DIP; clients should own the interface
Policy Layer > Mechanism Layer > Utility Layer
Policy Layer > Policy Service Interface, Mechanism Layer > Policy Service Interface
lower level layers are dependent upon upper level layers through the interface.
the client(upper level layer) owns the interface, not the lower level layers