Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Whoops! Where did my architecture go?

Whoops! Where did my architecture go?

Slides of my talk at jDays 2012.

977c74bb044a9d4fa90b305824eda390?s=128

Oliver Drotbohm

December 03, 2012
Tweet

Transcript

  1. Whoops! Where did my architecture go? Approaches to architecture management

    for Java and Spring applications Oliver Gierke
  2. Oliver Gierke SpringSource Engineer Spring Data ogierke@vmware.com olivergierke www.olivergierke.de

  3. Background 5 years of consulting Lots of code reviews Eoin

    Woods‘ talk on InfoQ
  4. Roadmap Architecture 101 A plain Java based approach Spring Plugin

  5. Architecture 101

  6. Know your dependencies

  7. Granularity Modules Layers Vertical slices Subsystems

  8. Granularity Java ARchive Package Class

  9. Of layers and slices…

  10. Presentation Service Data Access Account Customer Core

  11. Layers Well understood Known to developers Less important to business

  12. Slices Hardly understood New to developers Key for business req

  13. Presentation Service Data Access Account Customer Core

  14. "How to implement an architecture inside a codebase?

  15. Architecture VS. Codebase

  16. "How to implement an architecture inside a codebase?

  17. "How to maintain an architecture inside a codebase?

  18. Code analysis JDepend Sonar

  19. Demo

  20. Sonargraph Formerly known as SonarJ

  21. Demo

  22. A plain Java based approach

  23. "How far can we get with plain Java means only?

  24. Presentation Service Data Access Account Customer Core

  25. Packages

  26. …. layer.slice ? …. slice.layer ? … slice ?

  27. …web.core …service.core …repository.core

  28. …core.web …core.service …core.repository

  29. … core … customer … account

  30. Layers first Leaks slice internals Lower layers visible to everyone

  31. Slices first/only Start with package per slice Expose interfaces and

    domain types Keep implementations private
  32. Slices first/only Encapsulates business module Internals understood anyway

  33. "Start with less packages and the least visibility possible…

  34. Presentation Service Data Access Account Customer Core

  35. Presentation Service Data Access Account Customer Core

  36. Subsystems

  37. Background Risk management at German public bank Quite a few

    other SpringSource clients
  38. Systems grow big!

  39. Complexity & Change

  40. "How to localize change?

  41. "Separate frequent from infrequent change!

  42. Granularity Class Package Java ARchive

  43. Host SPI SPI SPI Plugin Plugin

  44. Context No OSGi Spring based Build-time composition Don‘t touch the

    host system
  45. Host Plugin Plugin App

  46. "How to make the host aware of the plugins?

  47. "How to dynamically collect Spring beans of a given type?

  48. classpath*:META-INF/ spring/plugin-context.xml

  49. Host SPI SPI SPI Plugin Plugin

  50. classpath*:META-INF/ spring/plugin-context.xml SPI SPI SPI META-INF/ spring/plugin- context.xml META-INF/ spring/plugin-

    context.xml
  51. @Component public class MyComponentImpl implements TransferService { private List<MyPlugin> plugins;

    @Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } … } public interface MyPlugin { void doSomething(); }
  52. Demo

  53. XML? Back in the days

  54. (XML?) Back in the days Probably not a big deal

    anymore
  55. Easy access?

  56. @Component public class MyComponentImpl implements TransferService { private List<MyPlugin> plugins;

    @Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } … } public interface MyPlugin { void doSomething(); }
  57. @Component public 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? } }
  58. Spring Plugin

  59. "The smallest plugin system ever!

  60. Plugins Selection criterion Callback method Let the implementation decide

  61. Registry Equipped with plugins Common access patterns

  62. 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); … }
  63. @Component public 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(); }
  64. @Component public 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()); } }
  65. OrderAware PluginRegistry Respects @Order/Ordered OAPR.reverse()

  66. Bells‘n‘whistles FactoryBean Spring namespace Lazy-eval

  67. Spring Plugin github.com/SpringSource/spring-plugin Apache 2.0

  68. Spring Integration2

  69. <bean class="….FirstSamplePlugin" /> <bean class="….SecondSamplePlugin" /> <int:channel id="input" /> <int:channel

    id="output" /> <int-plugin:dynamic-service-activator input-channel="input" outputChannel="output" plugin-type= "….MyPlugin" method= "myBusinessMethod" delimiter="payload" invocation-arguments= "payload" />
  70. Demo

  71. Take-aways Know your dependencies On every granularity Start as strict

    as possible Get lenient where necessary
  72. Thanks & credits Eoin Woods - Talk @ InfoQ Uwe

    Friedrichsen - Slides @ Slideshare
  73. Resources Spring Data JPA @ GitHub Sonargraph Spring Plugin