Something About Layered Architecture Patterns: overlapped vs. concentric layers vs. SOLID
NunoSilva238662
0 views
44 slides
Oct 10, 2025
Slide 1 of 44
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
About This Presentation
Something About Layered Architecture Patterns: overlapped vs. concentric layers vs. SOLID
Size: 64.35 MB
Language: en
Added: Oct 10, 2025
Slides: 44 pages
Slide Content
Something about Layered Architecture patterns Overlapped vs. Concentric
(Classic) Layered Architecture
Architectural styles Layers vs. Tiers https:// www.baeldung.com /cs/layers-vs-tiers
Separation of concerns Each layer has a distinct responsibility, ensuring that business logic remains decoupled from infrastructure or presentation concerns. This separation improves code maintainability and facilitates testing. It allows developers to easily change or replace any layer without affecting the other layers. It also enables automated testing at each layer, which makes it easier to ensure the correctness and quality of the application.
Layers of Isolation The layers of isolation concept means that changes made in one layer of the architecture generally don’t impact or affect components in other layers: the change is isolated to the components within that layer, and possibly another associated layer (such as a persistence layer containing SQL). If you allow the presentation layer direct access to the persistence layer, then changes made to SQL within the persistence layer would impact both the business layer and the presentation layer, thereby producing a very tightly coupled application with lots of interdependencies between components. This type of architecture then becomes very hard and expensive to change. in https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html
Sink-hole (“ cano de esgoto ”) happens when, in a function, a layer does very little. How much can it happen? Typically, up to 20%.
Open layer is a layer that can is overpassed in some requests: the request is made to the layer not immediately bellow. How much can it happen? Depends on the architectural pattern.
SOLID (review) Single Responsibility Principle “A class should only have a single responsibility, that is, only changes to one part of the software's specification should be able to affect the specification of the class.” Open/Closed Principle "Software entities ... should be open for extension but closed for modification." Liskov Substitution Principle "Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program." Interface Segregation Principle "Many client-specific interfaces are better than one general-purpose interface." Dependency Inversion Principle “depend upon abstractions, [not] concretions” In Wikipedia: Martin, Robert C. (2000). "Design Principles and Design Patterns" (PDF). Archived from the original (PDF) on 2015-09-06.
Layered Architecture vs. SOLID Single Responsibility Principle Adopted: e ach layer (e.g. controller) has a single responsibility. Other components (e.g. DTO) has a single responsibility too. Open/Closed Principle Not explicitly adopted. Liskov Substitution Principle Not explicitly adopted. Interface Segregation Principle Not explicitly adopted. Should any API be segregated? How? Dependency Inversion Principle Not explicitly adopted. This layered architecture does not conform to clean/onion pattern/style.
From overlapped to concentric Adopting SOLID in Layer Architecture
Architecture Patterns adopting SOLID Hexagonal Architecture (a.k.a. Ports and Adapters) by Alistair Cockburn and adopted by Steve Freeman, and Nat Pryce in their wonderful book Growing Object Oriented Software 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 from: https:// blog.cleancoder.com /uncle-bob/2012/08/13/the-clean- architecture.html
Onion architecture
Clean Architecture
https :// herbertograca.com /2017/09/21/ onion-architecture / NB: The responsbilities assigned to the layers vary between models/patterns/styles. !!!!! Cf. next slide The adoption of DDD in Domain, implies that Repositories interfaces are defined in Domain. Cf. next slides.
Overlapped Layered Architecture This layered architecture does not conform to onion pattern/style. This is not what Onion pattern/style is about.
Each of these architectures produce systems that are Independent of Frameworks The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints. 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. in https:// blog.cleancoder.com /uncle-bob/2012/08/13/the-clean- architecture.html
Common characteristics Separation of Concerns The business logic (domain) is isolated from technical concerns (e.g., UI, database, external services). Dependency Inversion Higher-level modules should not depend on lower-level modules but on abstractions, allowing the core logic to remain independent. Testability and Maintainability By isolating dependencies and creating clear boundaries between layers, these architectures allow for easier unit testing and long-term maintenance. Business-related Technical-related
The Dependency Rule The concentric circles represent different areas of software. In general, the further in you go, the higher level the software becomes. The outer circles are mechanisms. The inner circles are policies. The overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the inner circle. That includes, functions, classes. variables, or any other named software entity. By the same token, data formats used in an outer circle should not be used by an inner circle, especially if those formats are generated by a framework in an outer circle. We don’t want anything in an outer circle to impact the inner circles. in https:// blog.cleancoder.com /uncle-bob/2012/08/13/the-clean- architecture.html
From overlapped to concentric: metaphoric representation
The dependency rule in simple code public class ControllerX { ServiceX _service ; public ControllerX ( ServiceX service ) { _service = service ; } public int method1 ( int value ) { X x1 = _service .method2( value ); return 1 ; } } public class ServiceX { IRepositoryX _repository ; public ServiceX ( IRepositoryX repository ) { _repository = repository ; } public X method2 ( int value ) { X x1 = new X( value ); return _repository .method3( x1 ); } } public class X { int _value ; X ( int value ) { _value = value ; } } public interface IRepositoryX { X method3 ( X x ); } public class RepositoryX2 implements IRepositoryX { public X method3 ( X x1 ) { // specific implementation 2 return x1 ; } } public class RepositoryX1 implements IRepositoryX { public X method3 ( X x1 ) { // specific implementation 1 return x1 ; } }
The dependency rule in simple code public class ControllerX { ServiceX _service ; public ControllerX ( ServiceX service ) { _service = service ; } public int method1 ( int value ) { X x1 = _service .method2( value ); return 1 ; } } public class ServiceX { IRepositoryX _repository ; IMsgAdapter _msgAdapter ; public ServiceX ( IRepositoryX repository, IMsgAdapter msgAdapter ) { _repository = repository ; _msgAdapter = msgAdpater; } public X method2 ( int value ) { X x1 = new X( value ); _r epository .method3( x1 ); _msgAdapter.sendMsg(“Funcionou!!”); } } public class X { int _value ; X ( int value ) { _value = value ; } } public interface IRepositoryX { X method3 ( X x ); } public class RepositoryX2 implements IRepositoryX { public X method3 ( X x1 ) { // specific implementation 2 return x1 ; } } public class RepositoryX1 implements IRepositoryX { public X method3 ( X x1 ) { // specific implementation 1 return x1 ; } } public interface IMsgAdapter { void sendMsg ( String s ); } public class MsgAdapterEmail implements IMsgAdapter { public void sendMsg ( S tring s ) { // specific implementation 2 return ; } } public class MsgAdapterSMS implements IMsgAdapter { public void sendMsg ( S tring s ) { // specific implementation 2 return ; } }
DIP: Dependency Inversion Principle The Domain Model define the contract that the Repository classes must implement. The Repository implements interface (contract). The Application Service does not need to know in development time the Repository class that implements the interface. Instead, the Repository class/object can be provided during execution (dependency injection). Hence, the Application Service behavior (i.e. which object is called) is controlled by the upper layers (Inversion of Control/Dependency Inversion Principle). Cf. next slides
Classify and layout layers ( i ) Colors are semantically meaningless but may help following from the onion metaphor diagram to the UML representation. BTW, what component should be here?
Classify and layout layers ( i ) (with isolation models) Colors are semantically meaningless but may help following from the onion metaphor diagram to the UML representation. e.g. HTTP Server+Routing ; or Tests , or UI
Including a filesystem-based repository Is it necessary? If its interface is different from that of the “Repository”, in order to apply the ISP, yes. Otherwise, no.
Just another layout
DIP: Dependency Inversion Principle The Domain Model define the contract that the Repository classes must implement. The Repository implements interface (contract). The Application Service does not need to know in development time the Repository class that implements the interface. Instead, the Repository class/object can be provided during execution (dependency injection). Hence, the Application Service behavior (i.e. which object is called) is controlled by the upper layers (Inversion of Control/Dependency Inversion Principle). Cf. next slides
Bootstrap Optional: the Container may be used to keep the injected objects. Dependency Injection in constructor. Dependency Injection.
Implementation View (from logic to implementation)
With or without inward interfaces? NB: because the dependency is from exterior to interior, it is not mandatory to adopt DIP, Interface or Dependency Injection.
Class diagram ( i ) (with inward interfaces)
Class diagram (ii) (with inward interfaces)
Class diagram (iii) (with inward interfaces)
Class diagram (iv) (with inward interfaces)
It would be uncommon that the DBDriver implements an interface defined in/by Repositories. It would be uncommon that the FilesystemDriver implements an interface defined in/by Repositories. Class diagram (v)
Sequence diagram (with DTO and DataModel )
References and Bibliography https://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same/ https://jeffreypalermo.com/tag/onion-architecture/ https://stackoverflow.com/questions/23479879/clean-architecture-vs-onion-architecture https://herbertograca.com/2017/09/21/onion-architecture/