Whoops! Where did my architecture go?

7,121 views
7,105 views

Published on

Slides of the talk at Spring I/O 2012

Published in: Technology
0 Comments
14 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
7,121
On SlideShare
0
From Embeds
0
Number of Embeds
1,654
Actions
Shares
0
Downloads
71
Comments
0
Likes
14
Embeds 0
No embeds

No notes for slide

Whoops! Where did my architecture go?

  1. 1. Whoops! Where did my architecture go?Approaches to architecture management for Java and Spring applications Oliver Gierke
  2. 2. Oliver GierkeSpringSource EngineerSpring Dataogierke@vmware.comolivergierkewww.olivergierke.de
  3. 3. Background 5 years of consulting Lots of code reviewsEoin Woods‘ talk on InfoQ
  4. 4. Roadmap Architecture 101A plain Java based approach Hera
  5. 5. The 3 C ofArchitecture Constraints Complexity Change © Uwe Friedrichsen
  6. 6. The 2 Cs ofArchitecture Complexity Change
  7. 7. Architecture 101
  8. 8. Know yourdependencies
  9. 9. Granularity Modules Layers Vertical slices Subsystems
  10. 10. Granularity Java ARchive Package Class
  11. 11. Of layersand slices…
  12. 12. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  13. 13. Layers Well understood Known to developersLess important to business
  14. 14. SlicesHardly understoodNew to developersKey for business req
  15. 15. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  16. 16. " How to implement an architecture inside a codebase?
  17. 17. Architecture VS. Codebase
  18. 18. " How to implement an architecture inside a codebase?
  19. 19. " How to enforce an architecture inside a codebase?
  20. 20. Code analysis JDepend Sonar
  21. 21. Demo
  22. 22. SonargraphFormerly known as SonarJ
  23. 23. Demo
  24. 24. A plain Javabased approach
  25. 25. " How far can we get with plain Java means only?
  26. 26. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  27. 27. Packages
  28. 28. ….${layer}.${slice} VS.….${slice}.${layer}
  29. 29. …domain.core …service.core…repository.core
  30. 30. …core.domain …core.service…core.repository
  31. 31. Layers first Leaks slice internalsLower layers visible to everyone
  32. 32. " Start with less packages and the least visibility possible…
  33. 33. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  34. 34. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  35. 35. Slices first Start with package per sliceExpose interfaces and domain types Keep implementations private
  36. 36. Slices firstEncapsulates business moduleInternals understood anyway
  37. 37. Subsystems
  38. 38. Background Risk mgmt. at German public bankQuite a few other SpringSource clients
  39. 39. Systemsgrow big!
  40. 40. Rememberthe 2 Cs?
  41. 41. Complexity & Change
  42. 42. " How to localize change?
  43. 43. " Separate frequent from infrequent change!
  44. 44. Granularity Class Package Java ARchive
  45. 45. HostSPI SPI SPI Plugin Plugin
  46. 46. Context No OSGi Spring based Build-time compositionDon‘t touch the host system
  47. 47. AppPlugin Plugin Host
  48. 48. " How to make the host aware of the plugins?
  49. 49. " How to dynamically collect Spring beans of a given type?
  50. 50. classpath*:META-INF/spring/plugin-context.xml
  51. 51. HostSPI SPI SPI Plugin Plugin
  52. 52. classpath*:META-INF/ spring/plugin-context.xmlSPI SPI SPI META-INF/ META-INF/spring/plugin- spring/plugin- context.xml context.xml
  53. 53. @Componentpublic class MyComponentImpl implements TransferService { private List<MyPlugin> plugins; @Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } …}public interface MyPlugin { void doSomething();}
  54. 54. Demo
  55. 55. XML?Back in the days
  56. 56. (XML?) Back in the daysProbably not a big deal anymore
  57. 57. Easy access?
  58. 58. @Componentpublic class MyComponentImpl implements TransferService { private List<MyPlugin> plugins; @Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } …}public interface MyPlugin { void doSomething();}
  59. 59. @Componentpublic class MyComponentImpl implements TransferService { // Constructor omitted public Result myMethod(SomeParameter parameter) { // Select the first one to match to invoke? // Select multiple ones to invoke? // Select and fallback to one if none found? // Select and throw an exception if none found? }}
  60. 60. Hera
  61. 61. " The smallest plugin system ever!
  62. 62. Plugins Selection criterion Callback methodLet the implementation decide
  63. 63. Registry Equipped with pluginsCommon access patterns
  64. 64. public interface Plugin<T> { public boolean supports(T delimiter );}public interface PluginRegistry<S extends Plugin<T>, T> { T getPluginFor(S delimiter); T getPluginFor(S delimiter, T default); <E extends Exception> T getPluginFor(S del, E e) throws E; List<T> getPluginsFor(S delimiter); …}
  65. 65. @Componentpublic class MyComponentImpl implements TransferService { private PluginRegistry<MyPlugin, String> plugins; @Autowired public MyComponentImpl( PluginRegistry<MyPlugin, String> plugins) { this.plugins = plugins; }}public interface MyPlugin extends Plugin<String> { void doSomething();}
  66. 66. @Componentpublic class MyComponentImpl implements TransferService { private final MyPlugin defaultPlugin = new MyDefaultPlugin(); public Result myMethod(String parameter) { // Select the first one to match to invoke? … = plugins.getPluginFor(parameter); // Select multiple ones to invoke? … = plugins.getPluginsFor(parameter); // Select and fallback to one if none found? … = plugins.getPluginFor(parameter, defaultPlugin); // Select and throw an exception if none found? … = plugins.getPluginsFor(parameter, new RuntimeException()); }}
  67. 67. OrderAwarePluginRegistryRespects @Order/Ordered OAPR.reverse()
  68. 68. Bells‘n‘whistles FactoryBean Spring namespace Lazy-eval
  69. 69. Herahttp://hera.synyx.org Apache 2.0Soon to be on GitHub
  70. 70. Spring Integration2
  71. 71. <bean class="….FirstSamplePlugin" /><bean class="….SecondSamplePlugin" /><int:channel id="input" /><int:channel id="output" /><int-hera:dynamic-service-activator input-channel="input" outputChannel="output" plugin-type= "….MyPlugin" method= "myBusinessMethod" delimiter="payload" invocation-arguments= "payload" />
  72. 72. Demo
  73. 73. Take-aways Know your dependencies On every granularity Start as strict as possibleGet lenient where necessary
  74. 74. Thanks & credits Eoin Woods - Talk @ InfoQUwe Friedrichsen - Slides @ Slideshare
  75. 75. ResourcesSpring Data JPA @ GitHub Sonargraph Hera

×