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

Whoops! Where did my architecture go?

Embed Size (px)

DESCRIPTION

Slides of the talk at Spring I/O 2012

Citation preview

Page 1: Whoops! Where did my architecture go?

Whoops!Where did my

architecture go?Approaches to architecture management for

Java and Spring applications

Oliver Gierke

Page 3: Whoops! Where did my architecture go?

Background5 years of consulting

Lots of code reviews

Eoin Woods‘ talk on InfoQ

Page 4: Whoops! Where did my architecture go?

RoadmapArchitecture 101

A plain Java based approach

Hera

Page 5: Whoops! Where did my architecture go?

The 3 C' of Architecture

Constraints

Complexity

Change

© Uwe Friedrichsen

Page 6: Whoops! Where did my architecture go?

The 2 C's of Architecture

Complexity

Change

Page 7: Whoops! Where did my architecture go?

Architecture 101

Page 8: Whoops! Where did my architecture go?

Know your dependencies

Page 9: Whoops! Where did my architecture go?

GranularityModules

Layers

Vertical slices

Subsystems

Page 10: Whoops! Where did my architecture go?

GranularityJava ARchive

Package

Class

Page 11: Whoops! Where did my architecture go?

Of layersand slices…

Page 12: Whoops! Where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 13: Whoops! Where did my architecture go?

LayersWell understood

Known to developers

Less important to business

Page 14: Whoops! Where did my architecture go?

SlicesHardly understood

New to developers

Key for business req

Page 15: Whoops! Where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 16: Whoops! Where did my architecture go?

"How to implement an architectureinside a codebase?

Page 17: Whoops! Where did my architecture go?

ArchitectureVS.

Codebase

Page 18: Whoops! Where did my architecture go?

"How to implement an architectureinside a codebase?

Page 19: Whoops! Where did my architecture go?

"How to enforcean architectureinside a codebase?

Page 20: Whoops! Where did my architecture go?

Code analysisJDepend

Sonar

Page 21: Whoops! Where did my architecture go?

Demo

Page 22: Whoops! Where did my architecture go?

SonargraphFormerly known as SonarJ

Page 23: Whoops! Where did my architecture go?

Demo

Page 24: Whoops! Where did my architecture go?

A plain Javabased approach

Page 25: Whoops! Where did my architecture go?

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

Page 26: Whoops! Where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 27: Whoops! Where did my architecture go?

Packages

Page 28: Whoops! Where did my architecture go?

….${layer}.${slice}VS.

….${slice}.${layer}

Page 29: Whoops! Where did my architecture go?

…domain.core…service.core

…repository.core

Page 30: Whoops! Where did my architecture go?

…core.domain…core.service

…core.repository

Page 31: Whoops! Where did my architecture go?

Layers firstLeaks slice internals

Lower layers visible to everyone

Page 32: Whoops! Where did my architecture go?

"Start with less packages and the least visibility possible…

Page 33: Whoops! Where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 34: Whoops! Where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 35: Whoops! Where did my architecture go?

Slices firstStart with package per slice

Expose interfaces and domain types

Keep implementations private

Page 36: Whoops! Where did my architecture go?

Slices firstEncapsulates business module

Internals understood anyway

Page 37: Whoops! Where did my architecture go?

Subsystems

Page 38: Whoops! Where did my architecture go?

BackgroundRisk mgmt. at German public bank

Quite a few other SpringSource clients

Page 39: Whoops! Where did my architecture go?

Systems grow big!

Page 40: Whoops! Where did my architecture go?

Remember the 2 C's?

Page 41: Whoops! Where did my architecture go?

Complexity& Change

Page 42: Whoops! Where did my architecture go?

"How to localize change?

Page 43: Whoops! Where did my architecture go?

"Separate frequent from infrequent change!

Page 44: Whoops! Where did my architecture go?

GranularityClass

Package

Java ARchive

Page 45: Whoops! Where did my architecture go?

Host

SPI SPI SPI

Plugin Plugin

Page 46: Whoops! Where did my architecture go?

ContextNo OSGi

Spring based

Build-time composition

Don‘t touch the host system

Page 47: Whoops! Where did my architecture go?

Host

Plugin Plugin

App

Page 48: Whoops! Where did my architecture go?

"How to make the host aware of the plugins?

Page 49: Whoops! Where did my architecture go?

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

Page 50: Whoops! Where did my architecture go?

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

Page 51: Whoops! Where did my architecture go?

Host

SPI SPI SPI

Plugin Plugin

Page 52: Whoops! Where did my architecture go?

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

SPI SPI SPI

META-INF/spring/plugin-

context.xml

META-INF/spring/plugin-

context.xml

Page 53: Whoops! Where did my architecture go?

@Componentpublic class MyComponentImpl implements TransferService {

private List<MyPlugin> plugins;

@Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } …}

public interface MyPlugin {void doSomething();

}

Page 54: Whoops! Where did my architecture go?

Demo

Page 55: Whoops! Where did my architecture go?

XML?Back in the days

Page 56: Whoops! Where did my architecture go?

(XML?)Back in the days

Probably not a big deal anymore

Page 57: Whoops! Where did my architecture go?

Easy access?

Page 58: Whoops! Where did my architecture go?

@Componentpublic class MyComponentImpl implements TransferService {

private List<MyPlugin> plugins;

@Autowired public MyComponentImpl(List<MyPlugin> plugins) { this.plugins = plugins; } …}

public interface MyPlugin {void doSomething();

}

Page 59: Whoops! Where did my architecture go?

@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?

}}

Page 60: Whoops! Where did my architecture go?

Hera

Page 61: Whoops! Where did my architecture go?

"The smallest plugin system ever!

Page 62: Whoops! Where did my architecture go?

PluginsSelection criterion

Callback method

Let the implementation decide

Page 63: Whoops! Where did my architecture go?

RegistryEquipped with plugins

Common access patterns

Page 64: Whoops! Where did my architecture go?

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);…

}

Page 65: Whoops! Where did my architecture go?

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

}

Page 66: Whoops! Where did my architecture go?

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

Page 67: Whoops! Where did my architecture go?

OrderAwarePluginRegistryRespects @Order/Ordered

OAPR.reverse()

Page 68: Whoops! Where did my architecture go?

Bells‘n‘whistlesFactoryBean

Spring namespace

Lazy-eval

Page 69: Whoops! Where did my architecture go?

Herahttp://hera.synyx.org

Apache 2.0

Soon to be on GitHub

Page 70: Whoops! Where did my architecture go?

Spring Integration2

Page 71: Whoops! Where did my architecture go?

<bean class="….FirstSamplePlugin" /><bean class="….SecondSamplePlugin" />

<int:channel id="input" /><int:channel id="output" />

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

Page 72: Whoops! Where did my architecture go?

Demo

Page 73: Whoops! Where did my architecture go?

Take-awaysKnow your dependencies

On every granularity

Start as strict as possible

Get lenient where necessary