0% found this document useful (0 votes)
14 views24 pages

AP2 Lecture 1 - Clean Architectuer Essentials

The document outlines the principles of Clean Architecture, emphasizing Separation of Concerns and Dependency Inversion to enhance software maintainability and scalability. It details the layered structure of Clean Architecture, including Entities, Use Cases, Adapters, and Frameworks, and discusses the implementation of Domain-Driven Design (DDD) in Golang. Key takeaways highlight the importance of managing dependencies and business logic separation to improve testability and flexibility in software development.

Uploaded by

akjshxhdhdh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views24 pages

AP2 Lecture 1 - Clean Architectuer Essentials

The document outlines the principles of Clean Architecture, emphasizing Separation of Concerns and Dependency Inversion to enhance software maintainability and scalability. It details the layered structure of Clean Architecture, including Entities, Use Cases, Adapters, and Frameworks, and discusses the implementation of Domain-Driven Design (DDD) in Golang. Key takeaways highlight the importance of managing dependencies and business logic separation to improve testability and flexibility in software development.

Uploaded by

akjshxhdhdh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 24

ADVANCED

PROGRAMMING II
LECTURE I –CLEAN
ARCHITECTURE ESSENTIALS
Shynggys Kairatuly Alshyno
MSc in I
[email protected]
OBJECTIVES

Clean Architecture Essentials:


 Principles of Clean Architecture (Separation of Concerns,
Dependency Inversion)
 Layered Architecture (Entities, Use Cases, Adapters,
Frameworks)
 Managing Dependencies and Business Logic Separation
 Implementing Domain-Driven Design (DDD) in Golang
 Structuring a Golang Project with Clean Code Principles
 Examples
 Conclusion
LEARNING OUTCOMES
At the end of this lecture, you will be able to:
• Understand the Principles of Clean Architecture
• Explain the importance of Separation of Concerns and Dependency Inversion in software design.
• Identify how these principles contribute to maintainability and scalability.
• Apply Layered Architecture in Software Development
• Differentiate between Entities, Use Cases, Adapters, and Frameworks.
• Organize software components into appropriate layers to promote modularity.
• Manage Dependencies and Business Logic Separation
• Implement dependency inversion to decouple core logic from external systems.
• Use interfaces and dependency injection to maintain clean and testable code.
• Implement Domain-Driven Design (DDD) in Golang
• Define Entities, Value Objects, Aggregates, and Repositories in a DDD approach.
• Structure Go applications following domain-driven best practices.
• Structure a Golang Project with Clean Code Principles
• Design a Go project using best practices for modularity and maintainability.
• Apply a well-organized folder structure to separate concerns.
• Develop and Evaluate Code Examples Based on Clean Architecture
• Write Go programs following Clean Architecture principles.
• Review and critique existing code for architectural improvements
WHAT IS SOFTWARE
ARCHITECTURE?
According to Robert C. Martin (a.k.a Uncle Bob):
Architecture is about Intentional Design
• It defines the boundaries between components and their responsibilities.
• It ensures separation of concerns for maintainability and scalability.
The Purpose of Architecture is to Support Business Logic
• The business rules should be independent of frameworks, databases, or
external systems.
• Good architecture enables easy modifications and testing.
The Primary Goal of Software Architecture is to Minimize Dependencies
• Architecture should ensure that high-level policies (core logic) do not depend
on low-level details (databases, UI, frameworks).
• This follows the Dependency Rule: “Nothing in the inner circle can know
anything at all about something in an outer circle.”
What is Clean Architecture?
Uncle Bob introduced Clean Architecture as a software
design philosophy focused on maintainability, scalability,
and independence from frameworks and external
dependencies.
He defines Clean Architecture as:
• "A set of principles and guidelines that help organize code in a
way that keeps the business logic separate from external
concerns such as UI, databases, and frameworks.“
KEY PRINCIPLES OF CLEAN
ARCHITECTURE
Separation of Concerns
• Different parts of the system should have clear responsibilities.
• Business logic should not depend on external details like databases or frameworks.
Dependency Inversion Rule
• High-level modules (business rules) should not depend on low-level modules (database, UI, frameworks).
• Both should depend on abstractions (e.g., interfaces in Go).
• Example: A repository interface in Go can be implemented with different databases without changing
business logic.
The Layered Structure
Clean Architecture is structured in layers, forming concentric circles:
• Entities (Core Business Rules): The most critical layer, containing enterprise-wide business rules.
• Use Cases (Application Logic): Contains the logic specific to the application’s functionality.
• Adapters (Interface Layer): Converts data between different layers (e.g., controllers, presenters).
• Frameworks & Drivers: Includes databases, UI, third-party libraries, and external APIs.
Rule: The inner layers should never depend on outer layers!This is called the Dependency Rule, where
higher-level logic should not depend on lower-level details.
Independence from External Tools & Frameworks
• The system should be framework-agnostic.
• You should be able to replace databases or UI frameworks without modifying business logic.
• Example: If you switch from PostgreSQL to MongoDB, your business logic remains unchanged.
CLEAN ARCHITECTURE MODEL
STRUCTU
RE
EXAMPLE
ENTITY LAYER
Sometimes can be named as
Core, Domain, Business
Purpose:
• Represents domain models with
business rules that do not
depend on external frameworks
Best Practice:
• Entities should be pure Go
structs with business logic
inside them, not database
concerns.
Bad practice:
• Adding json, bson, db or any
other tags that will add
dependency on something
USECASE LAYER
Sometimes can be named
application logic layer.
Purpose:
• Contains application-specific
business rules, orchestrating how the
system should behave.
Best Practice:
• Use cases should interact only with
abstractions (interfaces), not
concrete implementations.
• Does not depend on specific
databases or UI frameworks.
• Uses dependency injection
(AuthRepo as an interface).
Bad Practice:
• Use cases should not talk directly to
the database.
• Breaks the Dependency Rule by
depending on a specific database
implementation.
ADAPTER LAYER
Sometimes might be called as Interface
Layer.
Purpose:
• Acts as a bridge between external
interfaces (e.g., API, CLI) and the use case
layer.
Best Practice:
• Keep controllers thin—only handle
requests, call use cases, and return
responses.
• Controller only handles HTTP concerns
(request parsing, response writing).
• Delegates logic to the use case layer
(UserUseCase).
• Encapsulates API logic, making it easy to
swap with gRPC or CLI later.
Bad Practice:
• Handler should not contain business logic
or talk to DB directly
• Violates Single Responsibility Principle (SRP)
• Breaks Clean Architecture by bypassing the
use case layer
EXTERNAL LAYER
Layer that contains Frameworks,
drivers and other external stuff.
Purpose:
• Contains external dependencies
(ORMs, HTTP frameworks,
databases).
Best Practice:
• External tools should be confined
to this layer and kept replaceable.
• Encapsulates database logic inside
a repository.
• Implements an interface, so it can
be replaced with another
database.
• Does not affect the business logic
if we change the database*
Bad Practice:
• Direct database queries, global DB
access
MANAGING DEPENDENCIES AND
BUSINESS LOGIC SEPARATION
The Core Idea
• Uncle Bob emphasizes that business logic should remain
independent of external dependencies such as databases,
frameworks, UI, or third-party libraries. The goal is to ensure
that the core of an application is stable, testable, and
reusable, regardless of the technologies used.
Key principles:
• Dependency Inversion Principle (DIP)
• The Dependency Rule
• Separation of Concerns (SoC)
• Use of Interfaces and Dependency Injection (DI)
DEPENDENCY INVERSION PRINCIPLE
(DIP)
Definition:
• “High-level modules should not
depend on low-level modules. Both
should depend on abstractions.”
What does this mean?
• Business logic (high-level code)
should not directly depend on
infrastructure code (low-level
details).
• Both should depend on interfaces
(abstractions).
• This makes it possible to swap
dependencies (e.g., databases, API
clients) without affecting business
logic.
Bad Practice
• Hardcoded Dependency (e.g.
hardcoded queries (like I did before
with snippets, if you remember))
THE DEPENDENCY RULE
Definition:
• "Nothing in an inner circle should know anything at all about
something in an outer circle.“
How does this apply?
• Business logic (core layer) should never depend on
frameworks, databases, or external services.
• Dependencies should flow inwards: infrastructure should
depend on business rules, not vice versa.
SEPARATION OF CONCERNS (SOC)
Definition:
• "Each part of the system should only focus on its
responsibility, without depending on other parts
unnecessarily.“
Practical Example of SoC in a Golang Project: see project
structure example slide
DEPENDENCY INJECTION (DI)
Definition:
• "Dependencies should be
injected instead of being
hardcoded inside classes or
functions.“
Why is DI important?
• Allows flexible dependency
management (e.g., swap
database implementations).
• Improves testability (e.g., inject
mocks for unit tests).
• Reduces coupling between
components (easy to scale
and/or replace).
DOMAIN-DRIVEN DESIGN (DDD)
Definition:
• DDD is a software design approach introduced by Eric Evans,
focusing on modeling business logic through well-defined domain
concepts.
How DDD Aligns with Clean Architecture (Uncle Bob's
Approach)
• Entities & Value Objects: Represent the core business rules.
• Aggregates: Group related entities to maintain consistency.
• Repositories: Provide persistence abstraction.
• Use Cases (Application Services): Encapsulate business workflows.
• Interfaces & Infrastructure: Keep frameworks separate from business
logic.
DOMAIN-DRIVEN DESIGN (DDD)
Entity layer pros & cons:
Pros:
• ✔ Independent of databases, frameworks, or APIs.
• ✔ Contains only domain-specific logic.
• ✔ Can be tested without infrastructure dependencies.
Cons:
• ❌ Needs extra layers (repositories, adapters) to be fully functional.
DOMAIN-DRIVEN DESIGN (DDD)
Repository Interface (Abstraction) pros & cons:
Pros:
• ✔ Prevents business logic from knowing how data is stored.
• ✔ Supports swapping databases (MongoDB, PostgreSQL, etc.)
without changes to the core logic.
Cons:
• ❌ Requires separate implementations for each database type.
DOMAIN-DRIVEN DESIGN (DDD)
Use Case (Application Logic) pros & cons:
• Pros:
• ✔ Keeps business logic separate from data storage.
• ✔ Easily testable with mock repositories.
• ✔ Reusable across different user interfaces (API, CLI, gRPC).
Cons:
• ❌ Requires dependency injection for repository instances.
DOMAIN-DRIVEN DESIGN (DDD)
Repository Implementation (MongoDB) pros & cons:
Pros:
• ✔ Cleanly separates business logic from database interactions.
• ✔ Can swap MongoDB for PostgreSQL by implementing another
repository.
Cons:
• ❌ More boilerplate code compared to directly using an ORM.
DOMAIN-DRIVEN DESIGN (DDD)
Handler (Interface Layer) pros & cons:
Pros:
• ✔ Clean separation of concerns.
• ✔ Works with different frontends (CLI, API, gRPC).
Cons:
• ❌ Requires additional layers (use cases, repositories).
CONCLUSION
Key Takeaways:
Clean Architecture promotes maintainability and flexibility
• By following Separation of Concerns and Dependency Inversion, we keep business logic independent from
frameworks, databases, and external tools.
• This allows us to easily replace or update technologies without breaking core functionality.
A layered approach ensures clear responsibility distribution
• Entities contain core business rules.
• Use Cases define application logic.
• Adapters connect business logic with external tools (APIs, databases).
• Frameworks (databases, UI) remain in the outer layer to avoid direct dependencies.
Managing dependencies improves scalability and testability
• Using interfaces and dependency injection (DI) allows us to swap implementations (e.g., PostgreSQL,
MongoDB) without modifying business logic.
• This enhances unit testing, as we can use mock dependencies instead of real database connections.
DDD provides a structured way to model business logic
• Defining Entities, Value Objects, Aggregates, and Repositories ensures a clear domain model.
• Repositories encapsulate persistence logic, keeping business rules pure and framework-independent.
• Applying Use Cases ensures workflows remain organized and reusable.

You might also like