Whoops! where did my architecture go?

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

description

 

Transcript of Whoops! where did my architecture go?

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