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 33degree conference, Warszaw in March 2013

Oliver Drotbohm

March 15, 2013
Tweet

More Decks by Oliver Drotbohm

Other Decks in Programming

Transcript

  1. Whoops!
    Where did my
    architecture go?
    Approaches to architecture management for
    Java and Spring applications
    Oliver Gierke

    View Slide

  2. Oliver Gierke
    SpringSource Engineer
    Spring Data
    [email protected]
    olivergierke
    www.olivergierke.de

    View Slide

  3. Background
    5 years of consulting
    Lots of code reviews
    Eoin Woods‘ talk on InfoQ

    View Slide

  4. Macro VS. Micro
    Architecture

    View Slide

  5. Macro VS. Micro
    Architecture

    View Slide

  6. Sample Code
    http://github.com/olivergierke/
    whoops-architecture

    View Slide

  7. Roadmap
    Architecture 101
    A plain Java based approach
    Spring Plugin

    View Slide

  8. Architecture 101

    View Slide

  9. Know your
    dependencies

    View Slide

  10. Granularity
    Modules
    Layers
    Vertical slices
    Subsystems

    View Slide

  11. Granularity
    Java ARchive
    Package
    Class

    View Slide

  12. Of layers
    and slices…

    View Slide

  13. View Slide

  14. View Slide

  15. Presentation
    Service
    Data Access

    View Slide

  16. Presentation
    Service
    Data Access

    View Slide

  17. Presentation
    Service
    Data Access

    View Slide

  18. Presentation
    Service
    Data Access
    Account Customer Core

    View Slide

  19. Presentation
    Service
    Data Access
    Account Customer Core

    View Slide

  20. Presentation
    Service
    Data Access
    Account Customer Core

    View Slide

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

    View Slide

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

    View Slide

  23. Presentation
    Service
    Data Access
    Account Customer Core

    View Slide

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

    View Slide

  25. Architecture
    VS.
    Codebase

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  29. Code analysis
    JDepend
    Sonar

    View Slide

  30. Demo

    View Slide

  31. Sonargraph
    Formerly known as SonarJ

    View Slide

  32. Demo

    View Slide

  33. A plain Java
    based approach

    View Slide

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

    View Slide

  35. Presentation
    Service
    Data Access
    Account Customer Core

    View Slide

  36. Packages

    View Slide

  37. …. layer.slice ?
    …. slice.layer ?
    … slice ?

    View Slide

  38. …web.core
    …service.core
    …repository.core

    View Slide

  39. …core.web
    …core.service
    …core.repository

    View Slide

  40. … core
    … customer
    … account

    View Slide

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

    View Slide

  42. Slices first/only
    Start with package per slice
    Expose interfaces and domain types
    Keep implementations private

    View Slide

  43. Slices first/only
    Encapsulates business module
    Internals understood anyway

    View Slide

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

    View Slide

  45. Presentation
    Service
    Data Access
    Account Customer Core

    View Slide

  46. Presentation
    Service
    Data Access
    Account Customer Core

    View Slide

  47. Subsystems

    View Slide

  48. Background
    Risk management at German public bank
    Quite a few other SpringSource clients

    View Slide

  49. Systems
    grow big!

    View Slide

  50. Complexity
    & Change

    View Slide

  51. "How to localize
    change?

    View Slide

  52. "Separate frequent
    from infrequent
    change!

    View Slide

  53. Granularity
    Class
    Package
    Java ARchive

    View Slide

  54. Host

    View Slide

  55. Host
    SPI SPI SPI

    View Slide

  56. Host
    SPI SPI SPI
    Plugin Plugin

    View Slide

  57. Host
    SPI SPI SPI
    Plugin Plugin

    View Slide

  58. Host
    SPI SPI SPI
    Plugin Plugin

    View Slide

  59. Context
    No OSGi
    Spring based
    Build-time composition
    Don‘t touch the host system

    View Slide

  60. Host

    View Slide

  61. Host
    Plugin Plugin

    View Slide

  62. Host
    Plugin Plugin
    App

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  66. Host

    View Slide

  67. Host
    SPI SPI SPI

    View Slide

  68. Host
    SPI SPI SPI
    Plugin Plugin

    View Slide

  69. Host
    SPI SPI SPI
    Plugin Plugin

    View Slide

  70. Host
    SPI SPI SPI
    Plugin Plugin

    View Slide

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

    View Slide

  72. @Component
    public class MyComponentImpl implements TransferService {
    private List plugins;
    @Autowired
    public MyComponentImpl(List plugins) {
    this.plugins = plugins;
    }

    }
    public interface MyPlugin {
    void doSomething();
    }

    View Slide

  73. Demo

    View Slide

  74. XML?
    Back in the days

    View Slide

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

    View Slide

  76. Easy access?

    View Slide

  77. @Component
    public class MyComponentImpl implements TransferService {
    private List plugins;
    @Autowired
    public MyComponentImpl(List plugins) {
    this.plugins = plugins;
    }

    }
    public interface MyPlugin {
    void doSomething();
    }

    View Slide

  78. @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?
    }
    }

    View Slide

  79. Spring Plugin

    View Slide

  80. "The smallest plugin
    system ever!

    View Slide

  81. Plugins
    Selection criterion
    Callback method
    Let the implementation decide

    View Slide

  82. Registry
    Equipped with plugins
    Common access patterns

    View Slide

  83. public interface Plugin {
    public boolean supports(T delimiter );
    }
    public interface PluginRegistry, T> {
    T getPluginFor(S delimiter);
    T getPluginFor(S delimiter, T default);
    T getPluginFor(S del, E e) throws E;
    List getPluginsFor(S delimiter);

    }

    View Slide

  84. @Component
    public class MyComponentImpl implements TransferService {
    private PluginRegistry plugins;
    @Autowired
    public MyComponentImpl(
    PluginRegistry plugins) {
    this.plugins = plugins;
    }
    }
    public interface MyPlugin extends Plugin {
    void doSomething();
    }

    View Slide

  85. @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());
    }
    }

    View Slide

  86. OrderAware
    PluginRegistry
    Respects @Order/Ordered
    OAPR.reverse()

    View Slide

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

    View Slide

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

    View Slide

  89. Spring Integration2

    View Slide





  90. input-channel="input"
    outputChannel="output"
    plugin-type= "….MyPlugin"
    method= "myBusinessMethod"
    delimiter="payload"
    invocation-arguments= "payload" />

    View Slide

  91. Demo

    View Slide

  92. Take-aways
    Know your dependencies
    On every granularity
    Start as strict as possible
    Get lenient where necessary

    View Slide

  93. Thanks & credits
    Eoin Woods - Talk @ InfoQ
    Uwe Friedrichsen - Slides @ Slideshare

    View Slide

  94. Resources
    Spring Data JPA @ GitHub
    Sonargraph
    Spring Plugin

    View Slide