whoops! where did my architecture go?

81
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

41.383 views

Category:

Technology


4 download

DESCRIPTION

 

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 Java packages model

Hera

Page 5: Whoops! where did my architecture go?

Architecture 101

Page 6: Whoops! where did my architecture go?

Know your dependencies

Page 7: Whoops! where did my architecture go?

GranularityModules

Layers

Vertical slices

Subsystems

Page 8: Whoops! where did my architecture go?

GranularityJava ARchive

Package

Class

Page 9: Whoops! where did my architecture go?

Of layersand slices…

Page 10: Whoops! where did my architecture go?
Page 11: Whoops! where did my architecture go?
Page 12: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

Page 13: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

Page 14: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

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?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 17: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 18: Whoops! where did my architecture go?

LayersWell understood

Known to developers

Less important to business

Page 19: Whoops! where did my architecture go?

SlicesHardly understood

New to developers

Key for business req

Page 20: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 21: Whoops! where did my architecture go?

"How to implement an architectureinside a codebase?

Page 22: Whoops! where did my architecture go?

ArchitectureVS.

Codebase

Page 23: Whoops! where did my architecture go?

"How to implement an architectureinside a codebase?

Page 24: Whoops! where did my architecture go?

"How to implement an architectureinside a codebase?

Page 25: Whoops! where did my architecture go?

"How to enforcean architectureinside a codebase?

Page 26: Whoops! where did my architecture go?

Code analysisJDepend

Sonar

Page 27: Whoops! where did my architecture go?

Demo

Page 28: Whoops! where did my architecture go?

SonargraphFormerly known as SonarJ

Page 29: Whoops! where did my architecture go?

Demo

Page 30: Whoops! where did my architecture go?

A plain Javabased approach

Page 31: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 32: Whoops! where did my architecture go?

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

….${slice}.${layer}

Page 33: Whoops! where did my architecture go?

Layers firstLeaks slice internals

Lower layers visible to everyone

Page 34: Whoops! where did my architecture go?

"Start with less packages and the least visibility possible…

Page 35: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 36: Whoops! where did my architecture go?

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 37: Whoops! where did my architecture go?

Slices firstStart with package per slice

Expose interfaces and domain types

Keep implementations private

Page 38: Whoops! where did my architecture go?

Slices firstEncapsulates business module

Internals understood anyway

Page 39: Whoops! where did my architecture go?

Subsystems

Page 40: Whoops! where did my architecture go?

BackgroundRisk mgmt. at German public bank

Quite a few other SpringSource clients

Page 41: Whoops! where did my architecture go?

Host

Page 42: Whoops! where did my architecture go?

Host

SPI SPI SPI

Page 43: Whoops! where did my architecture go?

Host

SPI SPI SPI

Plugin Plugin

Page 44: Whoops! where did my architecture go?

Host

SPI SPI SPI

Plugin Plugin

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

Page 48: Whoops! where did my architecture go?

Host

Plugin Plugin

Page 49: Whoops! where did my architecture go?

Host

Plugin Plugin

App

Page 50: Whoops! where did my architecture go?

"How to make the host aware of the plugins?

Page 51: Whoops! where did my architecture go?

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

Page 52: Whoops! where did my architecture go?

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

Page 53: Whoops! where did my architecture go?

Host

Page 54: Whoops! where did my architecture go?

Host

SPI SPI SPI

Page 55: Whoops! where did my architecture go?

Host

SPI SPI SPI

Plugin Plugin

Page 56: Whoops! where did my architecture go?

Host

SPI SPI SPI

Plugin Plugin

Page 57: Whoops! where did my architecture go?

Host

SPI SPI SPI

Plugin Plugin

Page 58: 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 59: 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 60: Whoops! where did my architecture go?

Demo

Page 61: Whoops! where did my architecture go?

XML?Back in the days

Page 62: Whoops! where did my architecture go?

(XML?)Back in the days

Probably not a big deal anymore

Page 63: Whoops! where did my architecture go?

Easy access?

Page 64: 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 65: 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 66: Whoops! where did my architecture go?

Hera

Page 67: Whoops! where did my architecture go?

"The smallest plugin system ever!

Page 68: Whoops! where did my architecture go?

PluginsSelection criterion

Callback method

Let the implementation decide

Page 69: Whoops! where did my architecture go?

RegistryEquipped with plugins

Common access patterns

Page 70: 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 71: 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 72: 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 73: Whoops! where did my architecture go?

OrderAwarePluginRegistryRespects @Order/Ordered

OAPR.reverse()

Page 74: Whoops! where did my architecture go?

Bells‘n‘whistlesFactoryBean

Spring namespace

Lazy-eval

Page 75: Whoops! where did my architecture go?

Herahttp://hera.synyx.org

Apache 2.0

Soon to be on GitHub

Page 76: Whoops! where did my architecture go?

Spring Integration2

Page 77: 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 78: Whoops! where did my architecture go?

Demo

Page 79: Whoops! where did my architecture go?

Take-awaysKnow your dependencies

On every granularity

Start as strict as possible

Get lenient where necessary