5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 1/68
ARCHITECTING WELL-STRUCTURED JAVAAPPLICATIONS
Eduards Sizovs
@eduardsi
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 2/68
MOST APPS BEGIN LIFE SMALL AND NEAT.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 3/68
TIME GOES BY...
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 4/68
HELLO. I AM YOUR ROTTING ENTERPRISE APP.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 5/68
- RIGIDITY
- FRAGILITY
- IMMOBILITY
- VISCOSITY
- OPACITY
- NEEDLESS COMPLEXITY
- NEEDLESS REPITITION
SMELLING SYMPTOMS ->
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 6/68
HIBERNATE CORE V4.3.8.FINAL
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 7/68
JDK V1.7.0_51
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 8/68
A JDK CODE BASE IS DEEPLY INTERCONNECTED AT BOTH THE API AND THEIMPLEMENTATION LEVELS, HAVING BEEN BUILT OVER MANY YEARS
PRIMARILY IN THE STYLE OF A MONOLITHIC SOFTWARE SYSTEM. WE’VESPENT CONSIDERABLE EFFORT ELIMINATING OR AT LEAST SIMPLIFYING AS
MANY API AND IMPLEMENTATION DEPENDENCES AS POSSIBLE, SO THATBOTH THE PLATFORM AND ITS IMPLEMENTATIONS CAN BE PRESENTED AS A
COHERENT SET OF INTERDEPENDENT MODULES, BUT SOME PARTICULARLYTHORNY CASES REMAIN.
(C) MARK REINHOLDS, CHIEF ARCHITECT OF THE JAVA PLATFORM
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 9/68
SPRING V4.1.6
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 10/68
PRINCIPLES.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 11/68
PACKAGE IS THE FIRST-CLASS CITIZEN ANDKEY ELEMENT OF LOGICAL DESIGN.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 12/68
TREAT PACKAGES AS A HIERARCHY EVEN IFTHEY’RE REPRESENTED FLAT.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 13/68
io.shwitter.userio.shwitter.user.registrationio.shwitter.user.profileio.shwitter.timeline
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 14/68
io.shwitter.user (part of)io.shwitter.user.registrationio.shwitter.user.profileio.shwitter.timeline
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 15/68
io.shwitter.userio.shwitter.user.registration (part of)io.shwitter.user.profile io.shwitter.timeline
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 16/68
io.shwitter.userio.shwitter.user.registrationio.shwitter.user.profile (part of)io.shwitter.timeline
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 17/68
io.shwitter.userio.shwitter.user.registrationio.shwitter.user.profileio.shwitter.timeline (part of)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 18/68
USE PACKAGES TO GROUP FUNCTIONALLY-RELATED ARTIFACTS. DO NOT GROUPARTIFACTS THAT DO THE SAME THING, BUTARE DIFFERENT BY NATURE.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 19/68
io.shwitter.controllerio.shwitter.daoio.shwitter.domainio.shwitter.servicesio.shwitter.exceptions
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 20/68
io.shwitter.controllerio.shwitter.daoio.shwitter.domainio.shwitter.servicesio.shwitter.exceptions
io.shwitter.userio.shwitter.user.registrationio.shwitter.user.profileio.shwitter.timeline
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 21/68
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 22/68
- ABILITY TO DISTRIBUTE YOUR LAYERS OVER MULTIPLE PHYSICAL TIERS (HA-HA)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 23/68
- ABILITY TO DISTRIBUTE YOUR LAYERS OVER MULTIPLE PHYSICAL TIERS (HA-HA)
- DECOUPLING / ABSTRACTING FOR EXHANGEABILITY (HA-HA)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 24/68
- ABILITY TO DISTRIBUTE YOUR LAYERS OVER MULTIPLE PHYSICAL TIERS (HA-HA)
- DECOUPLING / ABSTRACTING FOR EXHANGEABILITY (HA-HA)
- DECOUPLING / ABSTRACTING FOR INDEPENDENT EVOLUTION (HA-HA)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 25/68
- ABILITY TO DISTRIBUTE YOUR LAYERS OVER MULTIPLE PHYSICAL TIERS (HA-HA)
- DECOUPLING / ABSTRACTING FOR EXHANGEABILITY (HA-HA)
- DECOUPLING / ABSTRACTING FOR INDEPENDENT EVOLUTION (HA-HA)
- DECOUPLING FOR REUSE (HA-HA)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 26/68
- ABILITY TO DISTRIBUTE YOUR LAYERS OVER MULTIPLE PHYSICAL TIERS (HA-HA)
- DECOUPLING / ABSTRACTING FOR EXHANGEABILITY (HA-HA)
- DECOUPLING / ABSTRACTING FOR INDEPENDENT EVOLUTION (HA-HA)
- DECOUPLING FOR REUSE (HA-HA)
- SEPARATION OF CONCERNS (IS PARTICULAR LAYER OUR CONCERN?)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 27/68
- ABILITY TO DISTRIBUTE YOUR LAYERS OVER MULTIPLE PHYSICAL TIERS (HA-HA)
- DECOUPLING / ABSTRACTING FOR EXHANGEABILITY (HA-HA)
- DECOUPLING / ABSTRACTING FOR INDEPENDENT EVOLUTION (HA-HA)
- DECOUPLING FOR REUSE (HA-HA)
- SEPARATION OF CONCERNS (IS PARTICULAR LAYER OUR CONCERN?)
- RELATED STUFF CO-LOCATION (ARE DAOS REALLY RELATED?)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 28/68
- ABILITY TO DISTRIBUTE YOUR LAYERS OVER MULTIPLE PHYSICAL TIERS (HA-HA)
- DECOUPLING / ABSTRACTING FOR EXHANGEABILITY (HA-HA)
- DECOUPLING / ABSTRACTING FOR INDEPENDENT EVOLUTION (HA-HA)
- DECOUPLING FOR REUSE (HA-HA)
- SEPARATION OF CONCERNS (IS PARTICULAR LAYER OUR CONCERN?)
- RELATED STUFF CO-LOCATION (ARE DAOS REALLY RELATED?)
- CONSTRAINT ENFORCEMENT (IS THERE A BETTER WAY?)
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 29/68
APPLY SERVICE-ORIENTED MINDSET TOSOFTWARE STRUCTURE.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 30/68
LAYERING IS YOUR SERVICE'S DETAIL AND ISINTERNAL TO THE SERVICE.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 31/68
GROUP TIGHTLY COUPLED CLASSESTOGETHER. IF CLASSES THAT CHANGETOGETHER ARE IN THE SAME PACKAGE, THENTHE IMPACT OF CHANGE IS LOCALIZED.
- THE COMMON CLOSURE PRINCIPLE
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 32/68
MAKE PACKAGES HIGHLY COHESIVE BYFOLLOWING SINGLE RESPONSIBILITYPRINCIPLE.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 33/68
io.shwitter.user.registrationio.shwitter.user.notificationsio.shwitter.user.profileio.shwitter.user.profile.blocking
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 34/68
io.shwitter.user.registrationio.shwitter.user.notificationsio.shwitter.user.profileio.shwitter.user.profile.blocking
io.shwitter.user :(
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 35/68
KEEP PACKAGES LOOSELY COUPLED, IDEALLY– COMPLETELY INDEPENDENT. REFLECTIONDOESN’T COUNT.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 36/68
package io.shwitter.user
@Entity class User { // name, password etc. }
package io.shwitter.timeline
@Entity class Timeline { @OneToOne User user; }
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 37/68
package io.shwitter.user
@Embeddable class UserId { Long value; }
package io.shwitter.timeline
@Entity class Timeline { @Embedded UserId userId; }
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 38/68
PROVIDE SLIM PACKAGE INTERFACE AND HIDEIMPLEMENTATION DETAILS.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 39/68
AVOID DEPENDENCY MAGNETS. SOMETIMESDUPLICATION IS NOT THAT EVIL.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 40/68
MANAGE RELATIONSHIPS. EVERYDEPENDENCY ARROW HAS A REASON.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 41/68
FINDBUGS V1.0 - A GREAT START
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 42/68
FINDBUGS V1.1 – IMPERFECTION CREEPS IN
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 43/68
FINDBUGS V1.2 – IMPERFECTION TAKES HOLD
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 44/68
FINDBUGS V1.3 – CHAOS BEGINS
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 45/68
FINDBUGS V1.4 – EXPLOSION
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 46/68
THE DEPENDENCIES BETWEEN PACKAGESMUST NOT FORM CYCLES. BURN BI-DIRECTIONAL DEPENDENCES IN FIRE.
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 47/68
HOW?
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 48/68
MERGING
package io.shwitter.userclass User { void register(RegistrationNotifier notifier) {}}
package io.shwitter.user.notifyclass RegistrationNotifier { void notify(User user) {}}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 49/68
MERGING - REPACKAGING
package io.shwitter.userclass User { void register(RegistrationNotifier notifier) {}}
class RegistrationNotifier { void notify(User user) {}}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 50/68
DEPENDENCY INVERSION
package io.shwitter.userclass User { void register(RegistrationNotifier notifier) {}}
package io.shwitter.user.notifyclass RegistrationNotifier { void notify(User user) {}}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 51/68
DEPENDENCY INVERSION - REFACTORING STEP 1
package io.shwitter.userclass User { void register(RegistrationNotifier notifier) {}}
package io.shwitter.user.notifyclass RegistrationNotifier implements UserNotifier { void notify(User user) {}}interface UserNotifier { void notify(User user) {} }
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 52/68
DEPENDENCY INVERSION - REFACTORING STEP 2
package io.shwitter.userclass User { void register(UserNotifier notifier) {}}
package io.shwitter.user.notifyclass RegistrationNotifier implements UserNotifier { void notify(User user) {}}interface UserNotifier { void notify(User user) {} }
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 53/68
DEPENDENCY INVERSION - REFACTORING STEP 3
package io.shwitter.userclass User { void register(UserNotifier notifier) {}}interface UserNotifier { void notify(User user) {} }
package io.shwitter.user.notifyclass RegistrationNotifier implements UserNotifier { void notify(User user) {}}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 54/68
ESCALATION
package io.shwitter.userclass User { void register(Notifier n) { n.notify(this); }}
package io.shwitter.user.notifyclass Notifier { void notify(User user) { sendEmailTo(user.email()); }}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 55/68
ESCALATION - REFACTORING STEP 1
package io.shwitter.userclass User { void register(Notifier n) { n.notify(this); }}
package io.shwitter.user.notifyclass Notifier { void notify(User user) { sendEmailTo(user.email()); }}
package io.shwitter.user.registration
class Registrator { void register(User user, Notifier n) {}}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 56/68
ESCALATION - REFACTORING STEP 2
package io.shwitter.userclass User { void register() { }}
package io.shwitter.user.notifyclass Notifier { void notify(User user) { sendEmailTo(user.email()); }}
package io.shwitter.user.registration
class Registrator { void register(User user, Notifier n) { n.notify(user); }}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 57/68
ESCALATION - REFACTORING STEP 3
package io.shwitter.userclass User { void register() { }}
package io.shwitter.user.notifyclass Notifier { void notify(String emailAddress) { sendEmailTo(emailAddress); }}
package io.shwitter.user.registration
class Registrator { void register(User user, Notifier n) { n.notify(user.email()); }}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 58/68
DEMOTION
package io.shwitter.userclass User { void register(Notifier n) { n.notify(this); }}
package io.shwitter.user.notifyclass Notifier { void notify(User user) { sendEmailTo(user.email()); }}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 59/68
DEMOTION - REFACTORING STEP 1
package io.shwitter.userclass User implements EmailHolder { void register(Notifier n) { n.notify(this); }}
package io.shwitter.user.notifyclass Notifier { void notify(User user) { sendEmailTo(user.email()); }}
package io.shwitter.emailer
interface EmailHolder { String email();}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 60/68
DEMOTION - REFACTORING STEP 2
package io.shwitter.userclass User implements EmailHolder { void register(Notifier n) { n.notify(this); }}
package io.shwitter.user.notifyclass Notifier { void notify(EmailHolder emailHolder) { sendEmailTo(emailHolder.email()); }}
package io.shwitter.emailer
interface EmailHolder { String email();}
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 61/68
TOOLS
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 62/68
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 63/68
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 64/68
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 65/68
OO Design Principles & Metrics, Jason Gorman http://goo.gl/RTW9GTThe Economics of Software Design, J.B. Rainsberger http://goo.gl/ra7Q8QSOLID Principles, Eduards Sizovs http://goo.gl/RpxavdDesigning Object-Oriented Software, Jouni Smed http://goo.gl/iyE1R2Grand Unified Theory Of Software Design, Jim Weirich http://goo.gl/ASqyAsFun With Modules, Kirk Knoernschild http://goo.gl/i8jx8YPatterns of Modular Architecture http://goo.gl/yFqmZOLet’s turn packages into a module system! http://goo.gl/Mzco8F
MORE
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 66/68
EITHER YOU WORK TO CREATE ASOFTWARE STRUCTURE OR YOU DON'T.EITHER WAY A STRUCTURE WILL EMERGE.
@EDUARDSI
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 67/68
THANK YOU
5/11/2015 Title
file:///Users/EDUARDSI/Desktop/well-structured-java-architectures/index.html#1 68/68
Top Related