Code Structural Analysis
Upcoming SlideShare
Loading in...5

Code Structural Analysis






Total Views
Views on SlideShare
Embed Views



2 Embeds 349 303 46



Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment
  • 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

Code Structural Analysis Code Structural Analysis Presentation Transcript

  • Code Structural Analysis
  • Eduards Sizovs @eduardsi on Twitter Who is broadcasting?
  • Agenda • Introduction to structural analysis • Logical Design principles • Q&A
  • Introduction to structural analysis
  • Most apps begin life small and neat.
  • Time goes by…
  • Hello. I am your rotting enterprise app.
  • How do we feel design rot?
  • Rigidity Fragility Immobility Viscosity Opacity Needless Complexity Needless Repetition There are different symptoms that smell…
  • What structural analysis shows…
  • Structure of Hibernate Core 3.6.6
  • Artwork by Jackson Pollock
  • However, it could be better…
  • Structure of Spring Framework 3.2.0
  • Structural analysis allows you to keep app’s structure in shape and catch design flaws early.
  • Logical Design principles
  • Package is the first-class citizen and key element of logical design.
  • Treat packages as hierarchical even if they’re represented flat.
  • Given packages com.myproject.client com.myproject.client.personal com.myproject.client.profile com.myproject.api Personal and Profile packages are part of Client.
  • Use packages to group functionally-related artifacts. Do not group artifacts that do the same thing, but are different by nature.
  • Avoid com.myproject.enums com.myproject.model com.myproject.repository com.myproject.factory com.myproject.helpers … Prefer com.myproject.client com.myproject.lending com.myproject.loyality …
  • 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.
  • Make sure artifacts are not floating away.
  • Make packages highly cohesive by following Single Responsibility Principle.
  • Keep packages loosely coupled, ideally – completely independent. Reflection doesn’t count.
  • Avoid dependency magnets. Sometimes duplication is not that evil.
  • Aggregate root relationship class Loan { } class Client { // a bunch of stuff } @ManyToOne Client client
  • Aggregate root relationship class Loan { } class Client { // a bunch of stuff } @Embedded ClientId clientId @Embeddable class ClientId { Long value }
  • Provide slim package interface and hide implementation details.
  • Strive for weak package connascence. Keep locality in mind.
  • Manage relationships. Every dependency arrow has a reason. Burn bi-directional dependences in fire.
  • Otherwise
  • Version 1.0 – A great start
  • Version 1.1 – Imperfection creeps in
  • Version 1.2 – Imperfection takes hold
  • Version 1.3 – Chaos begins
  • Version 1.4 – Explosion
  • The Acyclic Dependencies Principle The dependencies between packages must not form cycles.
  • Can be solved by: - Merging - Dependency Inversion - Escalation - Demotion
  • Client.Beans Merging Client Client
  • Tracking Dependency Inversion Guest TrackingGuest
  • Billing Escalation Customer class Customer { Collection<Bill> bills def calculateDiscount() { } } class Bill { def pay(Customer customer) { customer.calculateDiscount() … } }
  • Billing Escalation Customer class Customer { Collection<Bill> bills } class Bill { def pay(BigDecimal discount) { } } class DiscountCalculator { def calculate(Customer, Bills) } Discount
  • Billing Demotion Customer class Customer { Collection<Bill> bills def getDiscountCalculator() } class Bill { def pay(DiscountCalculator) { } } class DiscountCalculator { def calculate() } Discount
  • Class design principles (SOLID)
  • Single Responsibility Principle Open-Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
  • Class should have only one responsibility and only one reason to change. The Single Responsibility Principle
  • 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
  • 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»
  • Tools Macker JDepend
  • OO Design Principles & Metrics, Jason Gorman The Economics of Software Design, J.B. Rainsberger SOLID Principles, Eduards Sizovs Designing Object-Oriented Software, Jouni Smed Grand Unified Theory Of Software Design, Jim Weirich Fun With Modules, Kirk Knoernschild More
  • 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
  • Wish you beautiful architectures.
  • Thank you!