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
8.
Sink-hole (“cano de
esgoto”)happens when, in
a function, a layer does
very little.
How much can it happen?
Typically, up to 20%.
9.
Open layer isa 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.
10.
SOLID (review)
• SingleResponsibility 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.
11.
Layered Architecture vs.SOLID
• Single Responsibility Principle
• Adopted: each 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.
Architecture Patterns adoptingSOLID
• 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
Overlapped Layered Architecture
Thislayered architecture
does not conform to
onion pattern/style.
This is not what
Onion pattern/style
is about.
18.
Each of thesearchitectures produce systems
that are
1. 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.
2. Testable
The business rules can be tested without the UI, Database, Web Server, or any other external element.
3. 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.
4. 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.
5. 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
19.
Common characteristics
• Separationof 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
20.
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
The dependency rule
insimple 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;
}
}
23.
The dependency rule
insimple 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);
_repository.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 MsgAdapterEm
IMsgAdapter {
public void sendMsg(Str
// specific implementa
return;
}
}
public c
IMsgAd
publi
// s
ret
}
}
24.
DIP: Dependency
Inversion Principle
TheDomain 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
25.
Classify and layoutlayers (i)
Colors are semantically
meaningless but may help
following from the onion
metaphor diagram to the
UML representation.
BTW, what
component should
be here?
26.
Classify and layoutlayers (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
27.
Including a filesystem-basedrepository
Is it necessary?
If its interface is different from
that of the “Repository”, in
order to apply the ISP, yes.
Otherwise, no.
DIP: Dependency
Inversion Principle
TheDomain 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
With or withoutinward interfaces?
NB: because the
dependency is from
exterior to interior, it is not
mandatory to adopt DIP,
Interface or Dependency
Injection.
It would beuncommon 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)
#8 Sink-hole: quando os pedidos não são tratados ou são pouco tratados por determinado closed layer.
Regra: ainda será em camadas se estes sink-holes (pouco ou nenhum tratamento numa camada) não ultrapassarem os 20%
#9 Open layer: determina que os pedido não têm que passar por essa camada.