whoops! where did my architecture go?

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

Upload: oliver-gierke

Post on 15-Jan-2015

5.329 views

Category:

Technology


2 download

DESCRIPTION

Slides of the talk at Spring I/O 2012

TRANSCRIPT

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