whoops! where did my architecture go?
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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/1.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/2.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Oliver Gierke
Spring DataCore/JPA/MongoDB
![Page 3: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/3.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/4.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/5.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Architecture 101
![Page 6: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/6.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Know your dependencies
![Page 7: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/7.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
GranularityModulesLayers
Vertical slicesSubsystems
![Page 8: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/8.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
GranularityJava ARchive
PackageClass
![Page 9: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/9.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Of layersand slices…
![Page 10: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/10.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/11.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/12.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/13.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/14.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/15.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
ArchitectureVS.
Codebase
![Page 16: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/16.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/17.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/18.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Code analysisJDepend
Sonar
![Page 19: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/19.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Demo
![Page 20: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/20.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
SonargraphFormerly known as SonarJ
![Page 21: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/21.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Demo
![Page 22: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/22.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
A plain Javabased approach
![Page 23: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/23.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/24.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/25.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/26.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/27.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/28.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/29.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/30.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/31.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Subsystems
![Page 32: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/32.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/33.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
"The smallest plugin systemever!
![Page 34: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/34.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/35.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/36.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Host
Plugin Plugin
App
![Page 37: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/37.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/38.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/39.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/40.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/41.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/42.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Demo
![Page 43: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/43.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/44.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/45.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Easy access?
![Page 46: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/46.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/47.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/48.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/49.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/50.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/51.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/52.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/53.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/54.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/55.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Hera
![Page 56: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/56.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/57.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Spring Integration2
![Page 58: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/58.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/59.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Demo
![Page 60: Whoops! Where did my architecture go?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/60.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/61.jpg)
© 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?](https://reader033.vdocuments.mx/reader033/viewer/2022042713/546d274eb4af9f662c8b5372/html5/thumbnails/62.jpg)
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
ResourcesSourcecode @ GitHub
Sonargraph