22. The Common Closure Principle
Group tightly coupled classes together. If
classes that change together are in the same
package, then the impact of change is
localized.
28. Aggregate root relationship
com.app.loan
class Loan {
}
com.app.client
class Client {
// a bunch of stuff
}
@Embedded
ClientId clientId
com.app.client
@Embeddable
class ClientId {
Long value
}
47. Class should have only one responsibility and only one
reason to change.
The Single Responsibility Principle
48. Depend on abstractions, as anything concrete is volatile
The Dependency Inversion Principle
High Level
Policy
Abstraction Abstraction
Impl. Impl.
Package Package
X Y
X Y
interface
X
Package Package
49. Client
B
Service
«Client A method»
«Client B method»
«Client C method»
Client
C
Client
A
Many client-specific interfaces are better than one
general-purpose interface
The Interface Segregation Principle
Interface A
«Client A method»
Client
B
Client
C
Client
A
Interface B
«Client B method»
Interface C
«Client C method»
Service
«Client A method»
«Client B method»
«Client C method»
51. OO Design Principles & Metrics, Jason Gorman http://goo.gl/RTW9GT
The Economics of Software Design, J.B. Rainsberger http://goo.gl/ra7Q8Q
SOLID Principles, Eduards Sizovs http://goo.gl/Rpxavd
Designing Object-Oriented Software, Jouni Smed http://goo.gl/iyE1R2
Grand Unified Theory Of Software Design, Jim Weirich http://goo.gl/ASqyAs
Fun With Modules, Kirk Knoernschild http://goo.gl/i8jx8Y
More
52. Conclusion
Every application requires structure.
Structure must be carefully managed.
Integrate Code Structural Analysis into development:
• Install CSA tool
• Look at the «big picture»
• Manage complexity
• Prevent entropy
Rigidity (стойкость) – изменение аффектит слишком много зависимостей (МНОГО ЗАВИСИМОСТЕЙ ОТ МОДУЛЯ)Fragility (хрупкость) – поломка в разных местах без конфептуальной связиImmobility (немобильность, тяжеловесность) – невозможность зареюзать компоненты, хвост зависимостей, сложно сделать декомпозицию (МНОГО ТЯНЕТ ЗА СОБОЙ КУЧУ)Viscosity (вязкость) – when normal change is harder to employ than hack due to design (not clear wtf) or environment (compilation 1H)Opacity – не понятна суть и предназначение артифакта, взаимосвязиNeedless Complexity – чтобы сделать что-нибудь, приходится городитьNeedless Repetition – один и тот же функционал в разных кодовых проявлениях
- Being Related!= Part of- Packages under Client can be tightly coupled. With an API around.- An Aggregate Root with aggregates + functions- Or a Bounded context, for example.
It’s not about slices-first/layers-first fighting. It’s about grouping artifacts that are closely related.“DDD” packagingFunctional components are not visible at all. How to find relations between functional items. “What if I add this, how would it impact my functionality”?What should I do to extract functionality into a separate module? FAT is high that will force you to break logical module into functional. Then you’ll end up with mess managing this layering.Ok, provide API on top.
Shotgun surgery instead of localized changes (imagine I move client somewhere). Imagine I put a class that changes frequently into unrelated package. It will change every time as well!
I gain portability!!!For example, when mapping relationships, map using ID instead of Entity.Independence – talk to as few as possible. We become mobile, don’t care about incoming/outgoing dependencies
E.g. Client is used everywhere! Consider creating different clients. Ideally client can have different forms: Visitor, Client, Lender… Break client into smaller partsAbstract if there is chance that client code will have different cadence (out of release scope)
Be conservative in what you expose.Introduce factories that hide implementations (Dependency Injection, Service Locators etc.)Make @Components package-privateSeparate “api” from “internal” packages and restrict access to “internal”Make sure “internal” depends on “api”, not opposite.
Two components are connascent if a change in one would require the other to be modified in order to maintain the overall correctness of the system.Strongconnescence – worse.Problem of connascence of order -> in order to achieve goal X, client package A has to invoke two methods from package B. If package A decide that B has to call something in between, or order change, it will break B. Solution: provide coarse-grained interface for goal X, for example.For example: Connascence of Name over Connescance of Entity when desigining entity relationships.
Reasons:No guidelines for developers.Unable to simply extract: unable to “levelize” to see what to physically extract for build parallelization