whoops! where did my architecture go?

62
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission. Whoops! Where did my architecture go? Approaches to architecture management for Java and Spring applications Oliver Gierke

Upload: oliver-gierke

Post on 18-Nov-2014

1.568 views

Category:

Technology


4 download

DESCRIPTION

Slides of my SpringOne 2011 talk on how to implement and enforce architecture in codebases.

TRANSCRIPT

Page 1: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

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

Oliver Gierke

Page 2: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Oliver Gierke

Spring DataCore/JPA/MongoDB

[email protected]

Page 3: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

BackgroundFew years of consulting

Lots of code reviewsEoin Woods‘ talk on InfoQ

Page 4: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

RoadmapArchitecture 101

A Java packages modelHera

Page 5: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Architecture 101

Page 6: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Know your dependencies

Page 7: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

GranularityModulesLayers

Vertical slicesSubsystems

Page 8: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

GranularityJava ARchive

PackageClass

Page 9: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Of layersand slices…

Page 10: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 11: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

LayersWell understood

Known to developersLess important to business

Page 12: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

SlicesHardly understoodNew to developers

Key for business req

Page 13: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 14: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

"How to implement an architectureinside a codebase?

Page 15: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

ArchitectureVS.

Codebase

Page 16: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

"How to implement an architectureinside a codebase?

Page 17: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

"How to enforcean architectureinside a codebase?

Page 18: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Code analysisJDepend

Sonar

Page 19: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Demo

Page 20: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

SonargraphFormerly known as SonarJ

Page 21: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Demo

Page 22: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

A plain Javabased approach

Page 23: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 24: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

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

….${slice}.${layer}

Page 25: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Layers firstLeaks slice internals

Lower layers visible to everyone

Page 26: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

"Start with less packages and the least visibility possible…

Page 27: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 28: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Layer 1

Layer 2

Layer 3

Slice A Slice B Slice C

Page 29: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Slices firstStart with package per slice

Expose interfaces and domain typesKeep implementations private

Page 30: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Slices firstEncapsulates business moduleInternals understood anyway

Page 31: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Subsystems

Page 32: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

BackgroundRisk mgmt. at German public bank

Quite a few other SpringSource clients

Page 33: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

"The smallest plugin systemever!

Page 34: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Host

SPI SPI SPI

Plugin Plugin

Page 35: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

ContextNo OSGi

Spring basedBuild-time composition

Don‘t touch the host system

Page 36: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Host

Plugin Plugin

App

Page 37: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

"How to make the host aware of the plugins?

Page 38: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

"How to dynami-cally collect Spring beans of a given type?

Page 39: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

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

Page 40: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

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

SPI SPI SPI

META-INF/spring/plugin-context.xml

META-INF/spring/plugin-context.xml

Page 41: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

@Componentpublic class MyComponentImpl implements TransferService {

private List<MyPlugin> plugins;

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

public interface MyPlugin {void doSomething();

}

Page 42: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Demo

Page 43: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

XML?Back in the days

Page 44: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

(XML?)Back in the days

Probably not a big deal anymore

Page 45: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Easy access?

Page 46: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

@Componentpublic class MyComponentImpl implements TransferService {

private List<MyPlugin> plugins;

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

public interface MyPlugin {void doSomething();

}

Page 47: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

@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 48: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

PluginsSelection criterionCallback method

Let the implementation decide

Page 49: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

RegistryEquipped with plugins

Common access patterns

Page 50: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

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 exception) throws E;

List<T> getPluginsFor(S delimiter);…

}

Page 51: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

@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 52: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

@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 53: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

OrderAwarePluginRegistryRespects @Order/Ordered

OAPR.reverse()

Page 54: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Bells‘n‘whistlesFactoryBean

Spring namespaceLazy-eval

Page 55: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Hera

Page 56: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Herahttp://hera.synyx.org

Apache 2.0Soon to be on GitHub

Page 57: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Spring Integration2

Page 58: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

<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 59: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Demo

Page 60: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Take-awaysKnow your dependencies

On every granularityStart as strict as possible

Get lenient where necessary

Page 61: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

Thanks & creditsEoin Woods - Talk @ InfoQ

Page 62: Whoops! Where did my architecture go?

© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.

ResourcesSourcecode @ GitHub

Sonargraph