2. What is good software architecture?
● Good architecture must be time-proof
● Architecture must change because of new business requirements,
not because of new technologies
● Good architecture must clearly communicate code purpose
● Being flexible in wrong places is bad example of software architecture
● Good architecture let's defer major decisions
11. Clean architecture
● Architectural style suitable for all platforms, languages and domains
● Abstract, more like “mindset” instead of concrete rules / frameworks
● Easily adoptable
12. ● Easily testable
● Independent from database
● Independent from frameworks
● Always ready to deploy
● High isolation of modules
Clean architecture
24. The center of your application is not the
database. Nor is it one or more of the
frameworks you may be using. The center
of your application is the use cases of your
application - Uncle Bob
25. Insurance company example
● The heart of insurance company business is insurance calculation
formula which would determine correct price for insurance policy
and ensure profitable business model
○ Insurance calculation can be performed by human being with peace of paper and
calculator
○ It’s the Critical Business Rule, and can be delivered to customer via
Fax/Mail/Mobile App/Web
26. What is use-case ?
Wikipedia:
a use case is a list of actions or event steps typically defining the interactions
between a role (known in the Unified Modeling Language as an actor) and a
system to achieve a goal.
Clean Architecture book:
These use cases orchestrate the flow of data to and from the entities, and
direct those entities to use their Critical Business Rules to achieve the goals of
the use case.
27. Two cases of business rules
● Business specific business rules
○ Fundamental business rules
● Application specific business rules
○ For example communication with user, validation
It’s important to separate those rules in application architecture
28. Software dependency
● In clean architecture we INVERT software dependencies for
○ Database
○ Framework
○ UI
29. How to invert dependency
Business
layer
AddCar
Database
layer
CarSqlDB
References
Business
layer
AddCar
Database
layer
CarSqlDB
Implements
ICarStore
References
30.
31.
32. Entities
● Represent your domain model
● Entities should be reusable in many
applications
● They encapsulate the most general/high-level
rules.
33. Entities
● Entity layer must contain only POCO (Plain old
CLR object) objects
○ Easy to migrate between different .NET versions
○ Easy serialization and caching
○ Easy testable
34. Use Cases
● Use cases are application specific business
rules
○ Changes should not impact the Entities
○ Changes should not be impacted by infrastructure such
as a database
● Orchestrate data flow from and to Entities
● Validators, exceptions, commands, queries and
interfaces
35. ● Layer where 3rd party code can be used
○ MVC, API controllers, presenters, all belong here
○ Entity Framework: DbContext, Migrations,
Configurations
● Implements interfaces defined in Use-Cases
level
● No code further in (use cases, entities) should
have any knowledge of the db
Controllers / Gateways / Presenters
36. ● OS functions, api clients, file system, GPIO
● Web Server, SQL Server, Redis cache
● You’re not writing much of this code, i.e. we use
SQL Server, but we don’t write it.
● These are the glue that hook the various layers
up (IoC container XML config)
DB / Devices / WEB / UI
37. Only 4 circles?
● No, the circles are schematic. You may find that you need more than
just these four.
● BUT: Dependency Rule always applies. Source code dependencies
always point inwards.
● As you move inwards the software grows more abstract, and
encapsulates higher level policies. The innermost circle is the most
general and most stable
● Layers can not skip layers
38. Crossing boundaries
● Data that can cross boundaries are only simple data structures
● They are called DTOs, ViewModels
● You can not pass database rows or whole entities
● Passed data structure must be most convenient for inner circle
39. Main component
● Every system has “main” component where everything is wired-up
● It mostly likely has references to all layers
● Usually it is IoC container register
● Application.Startup method
45. Clean Architecture in ASP.NET MVC 5
Author: Matthew Renze
https://www.matthewrenze.com/articles/clean-architecture-in-asp-net-mvc-5/
46. Screaming architecture
● Architecture based on use-cases and shows them on the first glance
● Same functionality put under same folders and easy to find (high
cohesion)
48. What about MVC?
● MVC is not an architecture
○ MVC was introduced in 1970s into Smalltalk
○ Intention was to use for small UI object (button, text input, circle)
○ MVC is a delivery design pattern
○ Should be in Presentation layer
49. What about testing?
● Clean architecture is very test-friendly
○ We can test our Entities and Use-cases (business logic) without database and UI
○ Test should be considered as outermost circle in the architecture
● Tests should be considered as first-class citizen of software
architecture
52. Northwind Traders in ASP .NET Core
https://github.com/JasonGT/NorthwindTraders
Clean Architecture with ASP.NET Core
https://www.youtube.com/watch?v=_lwCVE_
XgqI
54. Summary
● Business operations (use cases) are the most important thing!
Respect them and don’t pollute them with unnecessary things
● Database is only a Detail
● Frameworks are only the Details
● UI (Presentation) is a Detail
Architektūra turi būti tvari laikui. Ji turi būti pakankamai abstrakti kad leistų daryti pokyčius apie kuriuos dar nežinome ir pakankamai konkreti kad programuotojai nepridarytų sisteminių klaidų.
Jos nereikia “perrašinėti” nes niekas nesusigaudo kaip kas veikia.
Gera architektūra turi keistis dėl naujų verslo reikalavimų, o ne dėl naujų technologijų
“Mums viską reikia perrašyti nes išėjo naujas frameworkas”
Gera architektūra turi aiškiai komunikuoti programinės įrangos paskirtį (screaming architecture)
Architektūra turi atskleisti ketinimus o ne slėpti juos
Lankstumas netinkamose vietose yra blogos architektūros pavyzdys
Gera architektūra leidžia atidėlioti ir lengvai keisti jau priimtus sprendimus. Kuriant sistemos architektūra reikia daryti major technologinius sprendimus, kurie impactins ilgam laikui visą biznį, todėl logišą priiminėti tuos sprendimus kai turime daugiausiai informacijos ir žinių
Iliustruojantis pavyzdys
Mind-set’as “pataisyme vėliau”, ko pasekoje reikia mokėti palūkanas už techninę skolą
Dėl netinkamos architektūros tenka daryti hack’us ir workaroundus
Architektūros tikslas yra minimizuoti reikalingą žmogaus įsikišimą kurio reikia palaikyti ir plėtoti sistemą
Iš to išplaukia:
Turi būti lengva bugfix’inti
Turi būti lengva pridėti naujus features’u
Lengva onboardinti naujus developerius
Laikas skirtas bugfixinimui / naujiem featursams neturi augti bėgant metam
2017 metais išleido knygą kurioje aprašė “Clean architecture stilių”
daugiau nei 30 metų dirba IT industrijoje programuotojų prie visokių sistemų
Į šią knygą sudėjo kas jo manymu reikalinga padaryti gerą architektūra
Architektūrinis stilius skirtas bet kokiai platformai, kalbai ar domain’ui.
Abstraktus, labiau “mind-set” negu griežtos taisyklės ar frameworkas
Lengvai pritaikomas. Jeigu sistema kuriama nuo pradžių
Lengvai testuojama
Nepriklausoma nuo duomenų bazės
Nepriklausoma nuo framework’ų
Visada paruošta deploy’inimui
Izoliuoti moduliai
Švariai architektūrai reikia griežtų layer’ių, daug kodo skaidymo kartais yra netinkama mažiems MVP produktams
N-Tier / N-Layer
Use-case yra veiksmų visuma kuriuos vartotojas gali atlikti su aplikacija norėdamas pasiekti tam tikro rezultato.
Tie veiksmai dažniausiai būna tai dėl ko verslas gyvuoja ir kuriem automatizuoti kuriama aplikacija
Mūsų atveju use-case orkestruoja duomenų srautą tarp kritinių biznio operacijų ir vartotojo
Švarios architektūros pagrindinė idėja yra invertuoti priklausomybę.
Taigi duomenų bazė tampa tik “pluginas” į mūsų biznio logiką
Tas pats ir su framework’u ir UI
Taigi, grįžkime prie originalaus paveiksliuko
Kitoks tos pačios svogūno architektūros pjūvis
Kuo arčiau centro tuo daugiau abstrakcijos, tuo mažiau priklausomybių ir kodas mažiau keičiasi
Entičiai dažniausiai yra daiktavardžiai
Entičiai turėtų galėti būti perpnaudojami keliose aplikacijose. Gali būt platinami kaip vidiniai nuget paketai. Jie neturi nuo nieko priklausyti
Juose aprašomos labiausiai abstrakčios funkcijos ir struktūros, kurios rečiausiai keičiasi
Entity sluoksnyje turi būti tik vadinami POCO objektai. Pvz jame neturėtų būti asynchroninio, linq kodo
Lengva migruoti tarp skirtingų .net versijų
Lengva serelizuoti ir cachuoti
Lengva testuoti
Use case dažniausiai yra biznio operacijos specifinės kuriamai aplikacijai
Pakeitimai turėtų neįtakoti enticiu
Pakeitimai neturi įtakoti infrastruktūrinių dalykų tokių kaip duomenų bazė ar UI
Čia dedami validatoriai, exceptionai, komandos, queriai, interface’ai
Konvertuoja duomenis tarp Domain objektų ir duomenų bazės bei UI
Dažniausiai čia atsigula MVC Controlleriai
Taip pat čia gula ir EntifyFramework reikalai: DbContext, Migrations, Configurations
Taip pat čia konvertuojami duomenys iš išorinių servisų
Išoriniai servisai, failų sistema, hardware input/outputs, integracijos
Dauguma kodo čia parašyta ne mūsų, naudojam 3d party servisus
Web projektas pvz suklijuoja visus layerius tarpusavyje
Tik 4 layeriai?
Ne, jų gali būti kiek reikia
Bet: priklausomybės principas išlieka
kuo arčiau apskritimo vidurio, tuo kodas turi turėti mažiau priklausomybių ir būti abstraktersnis
Ribų kirtimas
Tik paprastos duomenų struktūros gali vaikščioti taip layerių
Negalima perdavinėti duomenų bazės objektų arba enticių iš centrinio apskritimo
Tam reikės naudoti mapperius
Duomenų struktūras derinti prie vidinio rato, nes išorinis ratas yra priklausomas nuo vidinio o ne atvirkščiai
Šios duomenų struktūros dažniausiai vadinamos DTO arba ViewModeliais
Folder-by-feature
Atsidarę projektą pirmiausia matome ne framework’ą, o biznio objektus
Architektūra paremta Use-Cases, o ne konkrečiu karkasu (framework)
Panašus funkcionalumas sutelktas į vieną vietą (high cohesion)
O kaip .net frameworkas?
Deje programuoti C# be .net frameworko neišeina
Reiktų naudoti kuo mažiau fancy featursu vidiniuose ratuose. Vidininiai ratai turi atitikti .NET Standarto specifikaciją
.NET frameworkas iš esmės labai stabilus ir tikėtina pergyvens kuriamą sistemą
Kaip “framework’ą reiktų laikyti MVC ASP. Jis žymiau labiau keitėsi negu .NET, dėl to ASP kodą reiktų laikyti išoriniame Presentation sluoksnyje. Jokiu būtų ne Application sluoksnyje
O kaip Clean architektūra dera su MVC architektūra?
Visų pirma MVC yra ne architetūra, o delivery patternas
Ji priklauso presenstation sluoksnyje
Iš esmes švari architektūra yra labai draugiška testam, nes kiekvienas komponentas turi aiškias ribas ir gali būti pakeistas į mocką
Pvz, WEB’ą galima užmokinti ir kviesti tiesiai Application layeri’į iš automatinų testų. Tą patį galima padaryti su duomenų baze.
Kuriant architektūrą testai turėtų būti laikomi tokie pat svarbūs kaip ir visi kiti moduliai. Jie neturi būti laikomi kažkas “už sistemos ribų”. Apie juos reikia pagalvoti nuo pat pirmų kodo eilučių nes vėliau integruoti gali būti sunku
Nedidelis startup template’as kurį galima atsisiųsti iš MarketPlace’o
Tik trys sluoksniai, pvz Core sluoksnyneje neišskrita Enterprise biznio logika ir Application biznio logika
Minimas oficiliam ASP .NET Guide
Visiem žinomas bet praktikoje dažnai užmirštamas Keep It Simple, Stupid principas. Kiss principas sako jog dauguma sistemų veikia geriau jeigu jos yra paprastos.
Paprastumas turėtų būti jūsų pagrindinis tikslas kuriant sistemą. Stenkitės vengti perdėto kompleksiškumo.
Plugin mindset. Duomenų bazė, framworkas, UI turi būti kaip plugin’ai į application branduolį.