More Related Content
Similar to Whoops! Where did my architecture go? (20)
Whoops! Where did my architecture go?
- 1. Whoops! Where did my architecture go?
Approaches to architecture management for Java and Spring applications
Oliver Gierke
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 2. Oliver Gierke
Spring Data
Core/JPA/MongoDB
ogierke@vmware.com
www.olivergierke.de
olivergierke
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 3. Background
Few years of consulting
Lots of code reviews
Eoin Woods‘ talk on InfoQ
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 4. Roadmap
Architecture 101
A Java packages model
Hera
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 6. Know your
dependencies
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 7. Granularity
Modules
Layers
Vertical slices
Subsystems
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 8. Granularity
Java ARchive
Package
Class
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 9. Of layers
and slices…
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 10. Slice A Slice B Slice C
Layer 1
Layer 2
Layer 3
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 11. Layers
Well understood
Known to developers
Less important to business
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 12. Slices
Hardly understood
New to developers
Key for business req
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 13. Slice A Slice B Slice C
Layer 1
Layer 2
Layer 3
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 14. " How to implement
an architecture
inside a codebase?
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 15. Architecture
VS.
Codebase
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 16. " How to implement
an architecture
inside a codebase?
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 17. " How to enforce
an architecture
inside a codebase?
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 18. Code analysis
JDepend
Sonar
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 20. Sonargraph
Formerly known as SonarJ
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 22. A plain Java
based approach
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 23. Slice A Slice B Slice C
Layer 1
Layer 2
Layer 3
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 24. ….${layer}.${slice}
VS.
….${slice}.${layer}
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 25. Layers first
Leaks slice internals
Lower layers visible to everyone
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 26. " Start with less
packages and the
least visibility
possible…
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 27. Slice A Slice B Slice C
Layer 1
Layer 2
Layer 3
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 28. Slice A Slice B Slice C
Layer 1
Layer 2
Layer 3
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 29. Slices first
Start with package per slice
Expose interfaces and domain types
Keep implementations private
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 30. Slices first
Encapsulates business module
Internals understood anyway
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 32. Background
Risk mgmt. at German public bank
Quite a few other SpringSource clients
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 33. " The smallest
plugin system
ever!
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 34. Host
SPI SPI SPI
Plugin Plugin
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 35. Context
No OSGi
Spring based
Build-time composition
Don‘t touch the host system
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 36. App
Plugin Plugin
Host
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 37. " How to make the
host aware of the
plugins?
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 38. " How to dynami-
cally collect Spring
beans of a given
type?
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 39. classpath*:META-INF/
spring/plugin-context.xml
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 40. classpath*:META-INF/
spring/plugin-context.xml
SPI SPI SPI
META-INF/spring/ META-INF/spring/
plugin-context.xml plugin-context.xml
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 41. @Component
public class MyComponentImpl implements TransferService {
private List<MyPlugin> plugins;
@Autowired
public MyComponentImpl(List<MyPlugin> plugins) {
this.plugins = plugins;
}
…
}
public interface MyPlugin {
void doSomething();
}
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 43. XML?
Back in the days
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 44. (XML?)
Back in the days
Probably not a big deal anymore
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 45. Easy access?
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 46. @Component
public class MyComponentImpl implements TransferService {
private List<MyPlugin> plugins;
@Autowired
public MyComponentImpl(List<MyPlugin> plugins) {
this.plugins = plugins;
}
…
}
public interface MyPlugin {
void doSomething();
}
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 47. @Component
public 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?
}
}
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 48. Plugins
Selection criterion
Callback method
Let the implementation decide
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 49. Registry
Equipped with plugins
Common access patterns
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 50. 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);
…
}
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 51. @Component
public 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();
}
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 52. @Component
public 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());
}
}
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 53. OrderAware
PluginRegistry
Respects @Order/Ordered
OAPR.reverse()
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 54. Bells‘n‘whistles
FactoryBean
Spring namespace
Lazy-eval
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 56. Hera
http://hera.synyx.org
Apache 2.0
Soon to be on GitHub
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 57. Spring
Integration 2
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 58. <bean class="….FirstSamplePlugin" />
<bean class="….SecondSamplePlugin" />
<int:channel id="input" />
<int:channel id="output" />
<int-hera:dynamic-service-activator
input-channel="input"
outputChannel="output"
plugin-type= "….MyPlugin"
method= "myBusinessMethod"
delimiter="payload"
invocation-arguments= "payload" />
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 60. Take-aways
Know your dependencies
On every granularity
Start as strict as possible
Get lenient where necessary
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 61. Thanks & credits
Eoin Woods - Talk @ InfoQ
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
- 62. Resources
Sourcecode @ GitHub
Sonargraph
© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.