Content
- Overview
- Architecture Organization
- Layered-Architectures
- Typical Layer Structure
- Example
- Layered-Architectures
- Sample Patterns Supporting Architecture
- Patterns
- Pattern Descriptions
- Model-View-Controller (MVC)
- Model-View-Presenter (MVP)
- Model-Template-View (MTV)
- Observer Pattern
- Facade Pattern
- Patterns
- Trends in Architecture
- CI/CD
- Continuous Integration (CI)
- Continuous Delivery & Continuous Deployment (CD)
- Microservices
- Hexagonal (Ports/Adapters) Architecture
- CI/CD
Overview
- Software architecting
- Decompose systems into subsystems providing some set of related services
- Establish a framework for their control and communication
- How components interact
- The components' interface
- All architecture is design
- Not all design is architecture
- Focus on external aspects of the components
- Places constraints on non-architectural design in order to meet its goals
- Architectural style
- Usually driven by non-functional requirements
- Security: structure in layers, important aspects protected within
- Performance: localize critical operations in a small number of subsystems with little communication between them
- Availability: redundant components so that they can be replaced/updated without stopping the system
- Maintainability: fine-grained, self-contained components that can be modified behind the interface
- A set of rules, constraints, and patterns for structuring a system into elements, connectors, and runtime interactions of control flow and data interaction
- Examples
- Monolithic
- Multi-tier
- Component-based
- Service-oriented
- Data-centric
- Event-driven
- Rule-based
- Distributed
- Usually driven by non-functional requirements
Architecture Organization
Layered-Architectures
- Problem
- Want to reduce dependencies
- Want better separation of concerns (e.g. logic with UI, infrastructure with logic)
- Solution
- Organize large-scale logical structure of the system into discrete layers
- Lower-layers provide low-level & general services
- Higher-layers are increasingly application-specific
- Collaboration and dependencies from higher-layers to lower-layers, but not the other way round
- Layers are conceptual and independent of deployment
Typical Layer Structure
- Strict layering: each layer depends on the layer exactly beneath it
- Relaxed layering: each layer depends on several layers beneath it
Layer | Description |
---|---|
UI | Shows info to actors; interprets actor requests |
Application | Defines services provided; manages transactions; delegates to/coordinates domain objects |
Domain | Business concepts & rules; heart of enterprise applications; important separation |
Technical Services | Infrastructure & framework |
- Spring web app
- .NET
Example
- Basic design principles
- Divide & conquer: each layer independently designed & worked on
- Hide information & increase abstraction: hide lower-layer implementation details
- Separation of concerns & increase cohesion: layers provide a set of related services and nothing else
- Reduce coupling: lower-layers don't know about higher-layers; connections between layers through API
- Quality characteristics and attributes
- Modifiability: easily add new facilities built on lower-layer services, or replace higher-layers
- Portability: all platform-dependent facilities can be isolated in one of the lower layers
- Testability: each layer tested independently
Sample Patterns Supporting Architecture
Patterns
Describes the core of solution to a commonly recurring problem. A form of knowledge reuse.
- Architectural patterns
- Large-scale, course-grained design
- Major structures & connections of system
- Design patterns
- Medium & small-scale design
- Design of frameworks, realization of architecture, solve problems of detailed design
Pattern Descriptions
- Pattern name
- Problem
- Solution
- Consequences
Model-View-Controller (MVC)
- Model: component with knowledge responsibilities about the domain
- View: visualizes state of component
- Controller: changes state of component, update model based on user input, select view to present
Model-View-Presenter (MVP)
Model-Template-View (MTV)
- Django
- The framework itself handles remaining responsibilities from View e.g. requests & URL routing
Observer Pattern
- Problem
- Want a subject to inform others to update whenever the state of the subjects changes without knowing about the other objects
- Solution
- Define observer (listener) interface; subjects maintain a collection of observer instances and inform them whenever there is state change
- Consequences
- Subjects and observers can be replaced independently
- Observers can be added without affecting subjects or other observers
- Subjects only know about the concrete observer instances -> no circular dependencies
Facade Pattern
- Problem
- Want a simple interface to a complex subsystem
- Solution
- Define a single point of contact to the subsystem in the form of a facade object
- Clients send messages to the facade, which redirects the messages to the appropriate object
- Subsystem objects have no knowledge about the facade
- Consequences
- Subsystem hidden behind the facade, making it easier to user
- Reduce decoupling between subsystem and client and hence compilation dependencies; components can be varied without affecting the clients
Trends in Architecture
CI/CD
Continuous Integration (CI)
Integrate whenever a developer completes a small piece of development (i.e. take iterative and incremental development to extreme).
- Idea
- Build and run automated integration tests locally
- Commit the code if no problem; each developer commit at least once a day
- CI server detects the commit and run the tests several times a day
- If build broken, fixing it is the top priority
- Team cooperation
- Developer team: make changes -> QA team
- QA team: manual testing, exploratory testing, user acceptance testing, non-functional testing, ... -> operation team
- Operation team: automate deployment process, manage release into production, monitor product in operation
- Inefficiencies
- Operation team waits for doc and fixes
- QA team waits for good builds; find architecture cannot support non-functional requirements
- Operation team waits for defect reports
Continuous Delivery & Continuous Deployment (CD)
- Continuous Delivery
- Code changes automatically built & deployed to test environment
- Manually deploy to production
- Continuous Deployment
- Automatic deployment as soon as the QA tests are passed
Deployment Pipeline
DevOps
Break down the walls among the teams to achieve close cooperation and rapid feedback. Aims to optimize the productivity of developers and reliability of operations.
You built it, you run it. You built it, you own it.
- Problems
- After a feature is added, the entire application has to be redeployed - monolith -> bottleneck in deployment pipeline
- Layered structure contains too many interdependencies within a single domain layer, which doesn't support different teams to work on different features
Microservices
Modularize the application, divide into small, well-defined services that run at distinct, self-contained processes.
- Idea
- Can be deployed independently
- Can use different technology and be scaled independently
- Can have different data source
- Loose coupling via explicit interfaces through network -> discourage unnecessary dependencies -> easy feature adding, refactoring, technology changing, ...
- Each microservice represents a domain, encapsulating part of the system-wide domain model
- The universal model is also split across microservices dealing with only attributes at interest
- Team formation
- Specilize in a layer?
- Each feature change has to involve all teams
- Create team around services
- Keep services independent
- Coordination between teams are minimized
- Each team owns several services, takes care from requirement engineering to operation monitoring
- Typically 3-9 people a team
- Specilize in a layer?
- UI
- Microservices provide RESTful interface to deliver data for other microservices' consumption
- UI delivers HTML and JavaScript
- Benefits
- Strong modularization
- Easy replacement
- Good way to extend legacy systems
- Scaled independently
- More robust: failures won't propagate
- Free choice of technology
- Easier to implement continuous deployment
- Challenges
- Higher complexity
- Needs to get the architecture right and minimize communication via network
- Needs to be robust in face of unreliable communication
- Too much freedom, needs some uniformity
- Refactoring across microservices is difficult
- Optimal architecture needed to achieve team independence
Hexagonal (Ports/Adapters) Architecture
Microservices have to provide interfaces for multiple clients, and we often want to replace them flexibly.
- Idea
- Keep core business logic from spreading
- Keep core business logic from dependencies on external services
- Communication to external services via ports
- Services connect to ports via adapters
- Ports: testing isolation is allowed
- Primary ports: APIs of application called by primary adapters used by user services
- Secondary ports: called by core logic to access services
- Ports can be split into smaller domain-based interfaces
- Adapters: converter from interface of class to that expected by the client; briding core logic and services
- Core logic: where the use case focus on
-