(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽❤️🧑🏻 89...
Clean sw 3_architecture
1. CeCoCo ENT 4.3
Clean Software: 3. Architecture (High Level)
15 April 2018
Angel Luis de Juan
Angel Luis Blasco
2. 2
INDEX
1. Leave details open as long as possible
2. Ways to decouple layers
3. Arquitecture history: Layers / Hexagonal / Clean
4. Layers
a) Names
b) Humble Object Pattern
c) Typical Scenario
d) Example: Hunt the wumpus
e) Example: Modules in java 9
5. Services & micro-services
6. Clean Embedded Arquitecture
7. Case Study 1: video Sales
8. Case Study 2: The devil is in the implementation details
Copyrights
3. 3
1. Leave details open as long as possible
• The architecture of a software system is the division of that system into
components, the arrangement of those components, and the ways in which those
components communicate with each other.
• The purpose is to facilitate the life cycle of the system: development, deployment,
operation, and maintenance. [Maintenance (digging) is the most costly]
Conway’s law: Any organization that designs a system will produce a design
whose structure is a copy of the organization´s communication structure
The strategy behind that facilitation is to leave as many options (details)
open as possible, for as long as possible. A good architect maximizes the
number of decisions not made.
4. 4
2. Ways to decouple layers
Ways to decouple layers
At the source code
level.
Controlling dependencies between source code modules.
Monolithic (same address space, communicate with
simple function calls) [fast and inexpensive]
At the binary code
(deployment)
Same address space functions calls
Or different process interprocess communication,
sockets, … [Mid-expensive]
At the execution
(service)
Communicate solely through network packets [very slow]
Best way is likely to change with time. Architect must foresee the future:
• YAGNI. The biggest mistake is over-architecture
• Change at the inflection point where cost of implementing < cost of ignoring
5. 5
3. Architecture history: a) Layers
• It´s database centered
• Examples:
− Ruby on Rails
− Active Record applications
6. 6
3. Architecture history: b) Hexagonal
Ports & Adapters:
• A port is an entry point, provided
by the core logic.
• An adapter is a bridge between
the application and the service
that is needed by the application.
It fits a specific port
7. 7
3. Architecture history: c) Clean
Source code dependencies can only point inwards
Don't depend on things that change a lot!
8. 8
4. Layers: a) Names
•Entities:
− Enterprise/Critical business rules. They are critical to the business, and would
exists even if the system were not automated.
− They are objects representing domain-specific concepts.
•Use Cases:
− Application Business Rules. Needed when system needs to be automated
− They are business rules defining and constraining the way that an automated
system operates. They are the rules that specify how and when entities are
invoked.
− Good architectures are centered on use cases, focussing on usability. Your
architecture should scream “I am a XXX(Control Center)”
•Interface adapters.
− Convert data Business Rules Details
− Ex: MVC of a GUI
9. 9
4. Layers: a) Names
•Framework is a detail. Asymmetric marriage:
− Author don´t know your problems and is asking you to marry the framework
− But the author makes no commitment to you
− Keep framework as a plugin to your business rules.
•Drivers are details.
− Are those things that enable humans, other systems, and programmers to
communicate with the policy
− IO devices, BBDD, GUI (web systems, …), frameworks, communication
protocols, …
− Main component is the ultimate detail, that creates & coordinates all the rest.
It´s a plugin, and so it´s possible to have many mains.
•Test layer:
− Tests are very detailed and concrete
− and they always depend inward toward the code being tested.
− Tests as the outermost circle in the architecture
10. 10
5. Layers. b) Humble Object pattern
Split the behaviors into two modules or
classes.
• One of those modules is humble; it
contains all the hard-to-test
behaviors stripped down to their
barest essence.
• The other module contains all the
testable behaviors that were
stripped out of the humble object
11. 11
4. Layers. c) Typical scenario
• String
• Flag
• Date
• Currency
Humble Humble
Date
String
12. 12
4. Layers. d) Example: Hunt the Wumpus
Architecture change with time. Architect must foresee the future:
• YAGNI. The biggest mistake is over-architecture
• Change at the inflection point where cost of implementing < cost of ignoring
13. 13
1.d) Layers. Example: Modules in Java 9
Module Group a set of related packages into
a group
Module-info module org.astro
{
exports org.astro;
requires org.astro;
}
JDK Contains ~ 100 jmods, all of them
depends on java.base
14. 14
5. Service & micro-services.
As useful as services are to the scalability and develop-ability of a
system, they are not architecturally significant elements.
Decoupling fallacy: Strongly
coupled by the data/resources
they share
Independent development/
deployment fallacy:
It must be coordinated
16. 16
6. Clean Embedded architecture
•Target-Hardware Bottleneck
•Hardware, Firmware and OS are details
•Avoid DRY. Conditional Compilation
•HAL =Hardware Abstraction Layer
•OSAL = Operating System Abstraction
Layer
Provides off-target & off-OS tests
Although software does not wear out,
firmware and hardware become obsolete,
thereby requiring software modifications
17. 17
7. Case Study 1: Video Sales
• User case analysis. To identify actors and user cases:
• We want to partition the system such that a change to one actor doesn´t affect others
18. 18
8. Case Study 2: The devil is in the implementation details
By Layer By Feature Ports&Adapters By Component
19. 19
Copyrights:
This powerpoint uses extracts from “Clean Architecture” book by Robert C.
Martin (Uncle Bob). All of this material is under Copyright of 2018 Pearson
Education, Inc
This powerpoint is only intended for educational purpose
The longer you leave options open, the more experiments you can run
YAGNI = You Aren´t Going to Need it
The decoupling mode of a system is one of those things that is likely to change with time:
With this approach, initially the components are separated at the source code level. That may be good enough for the duration of the project’s lifetime.
If, however, deployment or development issues arise, driving some of the decoupling to a deployment level may be sufficient—at least for a while.
As the development, deployment, and operational issues increase, I carefully choose which deployable units to turn into services, and gradually shift the system in that direction.
Over time, the operational needs of the system may decline. What once required decoupling at the service level may now require only deployment level or even source-level decoupling.
A good architecture will allow a system to be born as a monolith, deployed in a single file, but then to grow into a set of independently deployable units, and then all the way to independent services and/or micro-services. Later, as things change, it should allow for reversing that progression and sliding all the way back down into a monolith
Active Record =An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. An object carries both data and behavior. Much of this data is persistent and needs to be stored in a database. Active Record uses the most obvious approach, putting data access logic in the domain object. This way all people know how to read and write their data to and from the database.
Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database
Hexagonal Architecture (a.k.a. Ports and Adapters) by Alistair Cockburn 2005, and adopted by Steve Freeman, and Nat Pryce in their wonderful book Growing Object Oriented Software.
Application = Use cases. Ex: Register.
Can be a succession of atomic operations that can be reverted if not completed [transactional].
In charge of public events related with domain. Ex: new user
Hexagonal Architecture
Architecture or only a design patter (couple of good rules)? Hexagonal?
Data analysis: SemaText, Tableau, ElasticSearch,…
AWS= Amazon Web Service
A port is an entry point, provided by the core logic. [Think about an Interface, when implemented]
An adapter is a bridge between the application and the service that is needed by the application. It´s a tipical pattern design
Others:
Onion Architecture by Jeffrey Palermo
Screaming Architecture from a blog of mine last year
DCI from James Coplien, and Trygve Reenskaug.
BCE by Ivar Jacobson from his book Object Oriented Software Engineering: A Use-Case Driven Approach (http://www.artima.com/articles/dci_vision.html)
Post in 2012 by Robert C. Martin
Clean architectures produce systems that are:
Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software.
Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.
Data that crosses the boundaries consists of simple data structure
Design for testability:
Don´t use GUI to test business rules
interfaces provide the substitution point that facilitates off-target testing
Create a testing API, with superpowers to bypass expensive resources like the database (can be in a separate deployable component)
Create a testing API to hide the structure of the application
The Humble Object pattern: is a design pattern that was originally identified as a way to help unit testers to separate behaviors that are hard to test from behaviors that are easy to test. The idea is very simple: Split the behaviors into two modules or classes. One of those modules is humble; it contains all the hard-to-test behaviors stripped down to their barest essence. The other module contains all the testable behaviors that were stripped out of the humble object.
The Presenter: Its job is to accept data from the application and format it for presentation so that the View can simply move it to the screen.
For example, if the application wants a date displayed in a field, it will hand the Presenter a Dateobject. The Presenter will then format that data into an appropriate string and place it in a simple data structure called the View Model, where the View can find it.
Every button on the screen will have a name. That name will be a string in the View Model, placed there by the presenter. If those buttons should be grayed out, the Presenter will set an appropriate boolean flag in the View mode
3 ways to partially implement a boundary [YAGNI, You aren´t going to need it]. NO ME GUSTA
Skip the last step: Do all the work, but keep them together in the same component
One dimensional boundary: Only the interface that assure the dependency inversion
Façade pattern
The dashed outlines indicate abstract components that define an API that is implemented by the components above or below them. For example, the Language API is implemented by English and Spanish.
They are very popular
How many of those services will have to change to implement the new feature (kitty problem)? All of them. In other words, they are all coupled, and cannot be independently developed, deployed and maintained.
Services are just function calls across process and/or platform boundaries.
Services that simply separate application behaviors are just expensive function calls, and not necessary architecturally significant
I also found a file structure that implied that the only way to test any of this code is in the embedded target. Virtually every bit of this code knows it is in a special microprocessor architecture, using “extended” C constructs that tie the code to a particular tool chain and microprocessor
Target-Hardware Bottleneck: the scenario in which you can test your code only on the target. If the target is the only place where testing is possible, the target-hardware bottleneck will slow you down
As another example, an LED is tied to a GPIO bit:
The firmware could provide access to the GPIO bits, and provide Led_TurnOn(5)
HAL can provide Indicate_LowBattery()
The architecture diagram in Figure 33.2 includes two dimensions of separation. The first is the separation of actors based on the Single Responsibility Principle; the second is the Dependency Rule. The goal of both is to separate components that change for different reasons, and at different rates. The different reasons correspond to the actors; the different rates correspond to the different levels of policy.
By Simon Brown
Package by Layer: The first, and perhaps simplest, design approach is the traditional horizontal layered architecture, where we separate our code based on what it does from a technical perspective. This is often called “package by layer”: business rules, persistence, web
In java, layers are typically implemented as packages
It’s a very quick way to get something up and running without a huge amount of complexity.
The problem, as Martin points out, is that once your software grows in scale and complexity, you will quickly find that having three large buckets of code isn’t sufficient, and you will need to think about modularizing further.
Package by Feature: This is a vertical slicing, based on related features, domain concepts, or aggregate roots (to use domain-driven design terminology). In the typical implementations that I’ve seen, all of the types are placed into a single Java package, which is named to reflect the concept that is being grouped.
Ports & Adapters: Domain is in the inside, and infrastructure on the outside depends on the inside
Package by Component:
The dependency arrows still point downward, but the OrdersController is now additionally bypassing the OrdersService for some use cases. This organization is often called a relaxed layered architecture, as layers are allowed to skip around their adjacent neighbor(s)
A component is a grouping of related functionality behind a nice clean interface, which resides inside an execution environment like an application
A key benefit of the “package by component” approach is that if you’re writing code that needs to do something with orders, there’s just one place to go
This is akin to what you might end up with if you adopted a micro-services or Service-Oriented Architecture