Whoops!      Where did my     architecture go?Approaches to architecture management for      Java and Spring applications ...
Oliver GierkeSpringSource EngineerSpring Dataogierke@vmware.comolivergierkewww.olivergierke.de
Background  5 years of consulting  Lots of code reviewsEoin Woods‘ talk on InfoQ
Roadmap      Architecture 101A plain Java based approach           Hera
The 3 C ofArchitecture   Constraints   Complexity    Change    © Uwe Friedrichsen
The 2 Cs ofArchitecture   Complexity    Change
Architecture 101
Know yourdependencies
Granularity    Modules     Layers  Vertical slices  Subsystems
Granularity  Java ARchive    Package     Class
Of layersand slices…
Slice A   Slice B   Slice CLayer 1Layer 2Layer 3
Layers     Well understood  Known to developersLess important to business
SlicesHardly understoodNew to developersKey for business req
Slice A   Slice B   Slice CLayer 1Layer 2Layer 3
"   How to implement    an architecture    inside a codebase?
Architecture    VS. Codebase
"   How to implement    an architecture    inside a codebase?
"   How to enforce    an architecture    inside a codebase?
Code analysis    JDepend     Sonar
Demo
SonargraphFormerly known as SonarJ
Demo
A plain Javabased approach
"   How far can we get    with plain Java    means only?
Slice A   Slice B   Slice CLayer 1Layer 2Layer 3
Packages
….${layer}.${slice}        VS.….${slice}.${layer}
…domain.core …service.core…repository.core
…core.domain …core.service…core.repository
Layers first      Leaks slice internalsLower layers visible to everyone
"   Start with less    packages and the    least visibility    possible…
Slice A   Slice B   Slice CLayer 1Layer 2Layer 3
Slice A   Slice B   Slice CLayer 1Layer 2Layer 3
Slices first   Start with package per sliceExpose interfaces and domain types  Keep implementations private
Slices firstEncapsulates business moduleInternals understood anyway
Subsystems
Background Risk mgmt. at German public bankQuite a few other SpringSource clients
Systemsgrow big!
Rememberthe 2 Cs?
Complexity & Change
"   How to localize    change?
"   Separate frequent    from infrequent    change!
Granularity     Class    Package  Java ARchive
HostSPI       SPI        SPI Plugin          Plugin
Context         No OSGi       Spring based  Build-time compositionDon‘t touch the host system
AppPlugin          Plugin         Host
"   How to make the    host aware of the    plugins?
"   How to dynamically    collect Spring beans    of a given type?
classpath*:META-INF/spring/plugin-context.xml
HostSPI       SPI        SPI Plugin          Plugin
classpath*:META-INF/    spring/plugin-context.xmlSPI              SPI            SPI META-INF/              META-INF/sprin...
@Componentpublic class MyComponentImpl implements TransferService {    private List<MyPlugin> plugins;    @Autowired    pu...
Demo
XML?Back in the days
(XML?)       Back in the daysProbably not a big deal anymore
Easy access?
@Componentpublic class MyComponentImpl implements TransferService {    private List<MyPlugin> plugins;    @Autowired    pu...
@Componentpublic class MyComponentImpl implements TransferService {    // Constructor omitted    public Result myMethod(So...
Hera
"   The smallest plugin    system ever!
Plugins     Selection criterion      Callback methodLet the implementation decide
Registry Equipped with pluginsCommon access patterns
public interface Plugin<T> {    public boolean supports(T delimiter );}public interface PluginRegistry<S extends Plugin<T>...
@Componentpublic class MyComponentImpl implements TransferService {    private PluginRegistry<MyPlugin, String> plugins;  ...
@Componentpublic class MyComponentImpl implements TransferService {  private final MyPlugin defaultPlugin = new     MyDefau...
OrderAwarePluginRegistryRespects @Order/Ordered    OAPR.reverse()
Bells‘n‘whistles     FactoryBean   Spring namespace      Lazy-eval
Herahttp://hera.synyx.org    Apache 2.0Soon to be on GitHub
Spring   Integration2
<bean class="….FirstSamplePlugin" /><bean class="….SecondSamplePlugin" /><int:channel id="input" /><int:channel id="output...
Demo
Take-aways Know your dependencies   On every granularity Start as strict as possibleGet lenient where necessary
Thanks & credits     Eoin Woods - Talk @ InfoQUwe Friedrichsen - Slides @ Slideshare
ResourcesSpring Data JPA @ GitHub      Sonargraph         Hera
Upcoming SlideShare
Loading in...5
×

Whoops! Where did my architecture go?

5,814

Published on

Slides of the talk at Spring I/O 2012

Published in: Technology

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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×