Whoops! where did my architecture go?

41,973 views

Published on

Published in: Technology, Art & Photos
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
41,973
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
22
Comments
0
Likes
3
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 Java packages model Hera
  5. 5. Architecture 101
  6. 6. Know yourdependencies
  7. 7. Granularity Modules Layers Vertical slices Subsystems
  8. 8. Granularity Java ARchive Package Class
  9. 9. Of layersand slices…
  10. 10. Layer 1Layer 2Layer 3
  11. 11. Layer 1Layer 2Layer 3
  12. 12. Layer 1Layer 2Layer 3
  13. 13. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  14. 14. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  15. 15. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  16. 16. Layers Well understood Known to developersLess important to business
  17. 17. SlicesHardly understoodNew to developersKey for business req
  18. 18. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  19. 19. " How to implement an architecture inside a codebase?
  20. 20. Architecture VS. Codebase
  21. 21. " How to implement an architecture inside a codebase?
  22. 22. " How to implement an architecture inside a codebase?
  23. 23. " How to enforce an architecture inside a codebase?
  24. 24. Code analysis JDepend Sonar
  25. 25. Demo
  26. 26. SonargraphFormerly known as SonarJ
  27. 27. Demo
  28. 28. A plain Javabased approach
  29. 29. Slice A Slice B Slice CLayer 1Layer 2Layer 3
  30. 30. ….${layer}.${slice} VS.….${slice}.${layer}
  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. Host
  40. 40. HostSPI SPI SPI
  41. 41. HostSPI SPI SPI Plugin Plugin
  42. 42. HostSPI SPI SPI Plugin Plugin
  43. 43. HostSPI SPI SPI Plugin Plugin
  44. 44. Context No OSGi Spring based Build-time compositionDon‘t touch the host system
  45. 45. Host
  46. 46. Plugin Plugin Host
  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. Host
  52. 52. HostSPI SPI SPI
  53. 53. HostSPI SPI SPI Plugin Plugin
  54. 54. HostSPI SPI SPI Plugin Plugin
  55. 55. HostSPI SPI SPI Plugin Plugin
  56. 56. classpath*:META-INF/ spring/plugin-context.xmlSPI SPI SPI META-INF/ META-INF/spring/plugin- spring/plugin- context.xml context.xml
  57. 57. @Componentpublic class MyComponentImpl implements TransferService { private List<MyPlugin> plugins; @Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } …}public interface MyPlugin { void doSomething();}
  58. 58. Demo
  59. 59. XML?Back in the days
  60. 60. (XML?) Back in the daysProbably not a big deal anymore
  61. 61. Easy access?
  62. 62. @Componentpublic class MyComponentImpl implements TransferService { private List<MyPlugin> plugins; @Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } …}public interface MyPlugin { void doSomething();}
  63. 63. @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? }}
  64. 64. Hera
  65. 65. " The smallest plugin system ever!
  66. 66. Plugins Selection criterion Callback methodLet the implementation decide
  67. 67. Registry Equipped with pluginsCommon access patterns
  68. 68. 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); …}
  69. 69. @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();}
  70. 70. @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()); }}
  71. 71. OrderAwarePluginRegistryRespects @Order/Ordered OAPR.reverse()
  72. 72. Bells‘n‘whistles FactoryBean Spring namespace Lazy-eval
  73. 73. Herahttp://hera.synyx.org Apache 2.0Soon to be on GitHub
  74. 74. Spring Integration2
  75. 75. <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" />
  76. 76. Demo
  77. 77. Take-aways Know your dependencies On every granularity Start as strict as possibleGet lenient where necessary
  78. 78. Thanks & credits Eoin Woods - Talk @ InfoQ
  79. 79. ResourcesSpring Data JPA @ GitHub Sonargraph Hera

×