Successfully reported this slideshow.
Your SlideShare is downloading. ×

Code Structural Analysis


More Related Content


Related Books

Free with a 30 day trial from Scribd

See all

Code Structural Analysis

  1. 1. Code Structural Analysis
  2. 2. Eduards Sizovs @eduardsi on Twitter Who is broadcasting?
  3. 3. Agenda • Introduction to structural analysis • Logical Design principles • Q&A
  4. 4. Introduction to structural analysis
  5. 5. Most apps begin life small and neat.
  6. 6. Time goes by…
  7. 7. Hello. I am your rotting enterprise app.
  8. 8. How do we feel design rot?
  9. 9. Rigidity Fragility Immobility Viscosity Opacity Needless Complexity Needless Repetition There are different symptoms that smell…
  10. 10. What structural analysis shows…
  11. 11. Structure of Hibernate Core 3.6.6
  12. 12. Artwork by Jackson Pollock
  13. 13. However, it could be better…
  14. 14. Structure of Spring Framework 3.2.0
  15. 15. Structural analysis allows you to keep app’s structure in shape and catch design flaws early.
  16. 16. Logical Design principles
  17. 17. Package is the first-class citizen and key element of logical design.
  18. 18. Treat packages as hierarchical even if they’re represented flat.
  19. 19. Given packages com.myproject.client com.myproject.client.personal com.myproject.client.profile com.myproject.api Personal and Profile packages are part of Client.
  20. 20. Use packages to group functionally-related artifacts. Do not group artifacts that do the same thing, but are different by nature.
  21. 21. 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 …
  22. 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.
  23. 23. Make sure artifacts are not floating away.
  24. 24. Make packages highly cohesive by following Single Responsibility Principle.
  25. 25. Keep packages loosely coupled, ideally – completely independent. Reflection doesn’t count.
  26. 26. Avoid dependency magnets. Sometimes duplication is not that evil.
  27. 27. Aggregate root relationship class Loan { } class Client { // a bunch of stuff } @ManyToOne Client client
  28. 28. Aggregate root relationship class Loan { } class Client { // a bunch of stuff } @Embedded ClientId clientId @Embeddable class ClientId { Long value }
  29. 29. Provide slim package interface and hide implementation details.
  30. 30. Strive for weak package connascence. Keep locality in mind.
  31. 31. Manage relationships. Every dependency arrow has a reason. Burn bi-directional dependences in fire.
  32. 32. Otherwise
  33. 33. Version 1.0 – A great start
  34. 34. Version 1.1 – Imperfection creeps in
  35. 35. Version 1.2 – Imperfection takes hold
  36. 36. Version 1.3 – Chaos begins
  37. 37. Version 1.4 – Explosion
  38. 38. The Acyclic Dependencies Principle The dependencies between packages must not form cycles.
  39. 39. Can be solved by: - Merging - Dependency Inversion - Escalation - Demotion
  40. 40. Client.Beans Merging Client Client
  41. 41. Tracking Dependency Inversion Guest TrackingGuest
  42. 42. Billing Escalation Customer class Customer { Collection<Bill> bills def calculateDiscount() { } } class Bill { def pay(Customer customer) { customer.calculateDiscount() … } }
  43. 43. Billing Escalation Customer class Customer { Collection<Bill> bills } class Bill { def pay(BigDecimal discount) { } } class DiscountCalculator { def calculate(Customer, Bills) } Discount
  44. 44. Billing Demotion Customer class Customer { Collection<Bill> bills def getDiscountCalculator() } class Bill { def pay(DiscountCalculator) { } } class DiscountCalculator { def calculate() } Discount
  45. 45. Class design principles (SOLID)
  46. 46. Single Responsibility Principle Open-Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
  47. 47. Class should have only one responsibility and only one reason to change. The Single Responsibility Principle
  48. 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. 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»
  50. 50. Tools Macker JDepend
  51. 51. 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
  52. 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
  53. 53. Wish you beautiful architectures.
  54. 54. Thank you!

Editor's Notes

  • 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 -&gt; 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