� Mind The Gap! � Setting Up A Code Structure � Building Bridges
Representation Of Architectural Concepts In Code Structures
� Why do we need architecture? � Complex business problems � too many details to keep overview � Making „ big “ problems „ smaller “ � Separation of higher level aspects and their relations � Create abstract views with less details � Adds new complexity
� Why do we need architecture? � Functional view � Components � Layers � Cross-cutting concerns � Dependencies � Non-Functional view � Scalability � Robustness � Security
� Architect‘s view … … … …
� Developer‘s view
� Different roles � same objects, different views Architect Developer Representation Diagram Code (Text) Scope Broad Narrow Detail level Low (abstract) High (concrete) Reality Blue pill Red pill � The Gap � Diagram vs. Code � Architect vs. Developer
� Representation of architecture in code structures � Language elements with additional roles � Package � Layer � Class � Service � … � But: abstractions are not visible in code � How does the developer know about it? � Does even the architect know about it?
Representation Of Architectural Concepts In Code Structures
� Example – Yet Another Web Shop � High level functional requirements � User management � Product catalog � Shopping cart � Order-/payment � Shipping � High level non-functional requirements � Maintainable � Scalable � Robust
� Technology � Java EE Container Shop shop.war Deployable (Artifact)
� Deployment vs. Non-Functional Requirements � Scalability � Availability � Maintainability Artifacts Maven
� Deployable artifact per component � shop/ <groupId>com.acme.shop</groupId> � pom.xml <artifactId>parent</artifactId> � user/ <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> � pom.xml � catalog/ � pom.xml � cart/ <parent> <groupId>com.acme.shop</groupId> � pom.xml <artifactId>parent</artifactId> � order/ <version>1.0.0-SNAPSHOT</version> � pom.xml </parent> � shipping/ <artifactId>user</artifactId> � pom.xml <packaging>war</packaging>
� Layering a component � Root package = com.acme.shop.user REST API Web UI � � groupId + artifactId � com.acme.shop.user.rest Services � com.acme.shop.user.web � com.acme.shop.user.services.api � com.acme.shop.user.services.impl � com.acme.shop.persistence.dao Persistence � com.acme.shop.persistence.model DAO Model � Dependencies cannot be validated?!
� Class roles in layers � com.acme.shop.user.rest Rules developers � JAX-RS resources should know about � com.acme.shop.user.web � Models, views, controllers � Validators, converters � com.acme.shop.user.services Concepts architects � EJB should be aware � com.acme.shop.persistence.dao about � DAOs � com.acme.shop.persistence.model � JPA entities
� External dependencies of a component JAX-RS REST API Web UI JSF EJB Services CDI JMS Persistence JPA DAO Model
� External dependencies <parent> <groupId>com.acme.shop</groupId> <artifactId>user</artifactId> Valid for all <version>1.0.0-SNAPSHOT</version> components </parent> <packaging>war</packaging> <dependencies> <dependency> <groupId>javax.faces</groupId> Provided by <artifactId>faces-api</artifact> container <version>2.2</version> <scope>provided</scope> </dependency> </dependencies>
� Dependency Management <groupId>com.acme.shop</groupId> <artifactId>parent</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>pom</packaging> <dependencyManagement> <dependencies> <dependency> <groupId>javax.faces</groupId> <artifactId>faces-api</artifact> <version>2.2</version> <scope>provided</scope> </dependency> </dependencies> </dependencyManagement>
� Using managed dependencies <parent> <groupId>com.acme.shop</groupId> <artifactId>user</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <packaging>war</packaging> <dependencies> <dependency> <groupId>javax.faces</groupId> <artifactId>faces-api</artifact> </dependency> </dependencies>
� Dependencies between components cart catalog user order Synchronuous - REST Asynchronuous - JMS shipping
� Dependencies between components � Communication via remote protocols � REST over HTTP � JMS � Compile time dependencies � not explicitly required … � …but convenient! � Re-use code � Shared artifacts, i.e. libraries � APIs, domain models
<parent> � Splitting up a component <groupId>com.acme.shop</groupId> <artifactId>shop</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> � shop/ <artifactId>user</artifactId> � pom.xml <packaging>pom</packaging> � user/ <parent> � pom.xml <groupId>com.acme.shop</groupId> � api/ <artifactId>user</artifactId> <version>1.0.0-SNAPSHOT</version> � pom.xml </parent> � app/ <artifactId>user.api</artifactId> � pom.xml <parent> <groupId>com.acme.shop</groupId> � Visibilities <artifactId>user</artifactId> � api � public <version>1.0.0-SNAPSHOT</version> </parent> � app � private <artifactId>user.app</artifactId> <packaging>war</packaging>
� Splitting up a component <parent> <groupId>com.acme.shop</groupId> <artifactId>user</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>user.app</artifactId> <packaging>war</packaging> <dependency> <groupId>com.acme.shop</groupId> compile scope </artifactId>user.api</artifactId> </dependency>
� Use API of another component <parent> <groupId>com.acme.shop</groupId> <artifactId>cart</artifactId> <version>1.0.0-SNAPSHOT</version> </parent> <artifactId>cart.app</artifactId> <packaging>war</packaging> <dependency> <groupId>com.acme.shop</groupId> compile scope </artifactId>user.api</artifactId> </dependency>
� Deployment of libraries user.app.war cart.app.war cart.api.jar user.api.jar user.api.jar � Option: API versioning � Cart 2.1.0 Application � User 1.0 API � Requires further component separation
� Common functionality � common-core-shared-util-helper � Big balls of mud � Cover mostly technical aspects � layers � shop/ <parent> � common/ <groupId>com.acme.shop</groupId> � pom.xml <artifactId>common</artifactId> <version>1.0.0-SNAPSHOT</version> � rest/ </parent> � pom.xml <artifactId>common.web</artifactId> � web/ � pom.xml <dependencies> <dependency> � services/ <groupId>javax.faces</groupId> � pom.xml <artifactId>faces-api</artifactId> � persistence/ </dependency> � pom.xml </dependencies> � user/
� Component configuration � Artifacts that need to be delivered with deployables � Property-, XML, YAML-files, etc... � Migration scripts � user/ � pom.xml � api/ Deliverable artifacts � pom.xml (JAR, ZIP) � app/ � pom.xml � config/ � pom.xml
� Test code � Part of architecture � shop/ � test � *ST.java System � Components � user/test � *CT.java Component � Mockito � Component stubs � user/app Unit � *Test.java � Mockito
� Component stubs � Component tests require … � API and implementation of own component � APIs of other components � Stubs for other components � Stubs can be provided per owning component � user/test � src/main/java � com.acme.shop.user.test.UserManagementStub.java � Test module may depend on other test modules
� Structural overview � shop/ Libraries � common � rest � web � services Components � persistence with similar structures � test � user � api � app public vs. private artifacts � config � test � …
� Structural overview (continued) � … Layering in component � cart with defined content & � api dependencies � com.acme.shop.api � app � com.acme.shop.rest � com.acme.shop.ui � com.acme.shop.services � com.acme.shop.persistence Component test � config � test � … � test System test
� Some Observations � It‘s an evolution � Neither architecture nor code structures are static � Deployment is the starting point � Separate following requirements � Architecture is not only about packages � Build system defines core dependencies � Different roles – different views � Architect vs. Developer vs. Build-/Integrationmanager
Recommend
More recommend