Clean Architecture (CA)

Clean Architecture
with ASP.NET Core

Negzel - Clean Architecture

Clean Architecture (CA)

Introduction

Clean Architecture is a software architecture proposed by Robert C. Martin (Uncle Bob) that consists of independent layers. This architecture is highly beneficial in terms of controlling dependencies, code sustainability, and reusability. Ardalis Clean Architecture, on the other hand, is an approach based on Clean Architecture principles but enriched with practical applications and recommendations. In this document, we will examine in detail what Clean Architecture is, the differences of Ardalis Clean Architecture, why it should be preferred, its benefits, and possible disadvantages.

What is Clean Architecture?

Clean Architecture was developed to adapt the advantages of layered architectures to modern software development needs, providing independence and flexibility. The main goal in this architecture is that dependencies always flow from outer layers to inner layers. In other words, business rules and the domain (business logic) should not be dependent on the outside world; rather, the outer layers should depend on the business rules.

Clean Architecture Layers
  • Core Layers of Clean Architecture:

  • Entities: The innermost layer where business rules and domain logic reside. Contains the core business logic of the application.
  • Use Cases: Business rules that determine how the application behaves in different scenarios.
  • Interface Adapters: Manages the dependency between the database and web layers. Typically includes DTOs, Mappers, Repository interfaces, and similar components.
  • Infrastructure: Facilitates communication with the external world, such as data access and third-party service integrations.
  • Presentation: The layer that provides the user interface and manages interaction with the application (e.g., ASP.NET Core Web API, MVC).
  • Advantages of Using Clean Architecture

  • Control of Dependencies: By keeping dependencies away from business rules, the application's business logic is independent of data access and the external world. This increases testability.
  • Sustainability: Makes code maintenance and adding new features easier. Since it's domain-focused, even if business rules change, minimal changes are required on outer layers.
  • Testability: Keeping business logic in separate layers makes writing unit tests easier.
  • Reusability: It's possible to reuse a business rule in different applications or projects.
  • Flexibility and Adaptation: When a new data source or third-party service integration is needed, it's sufficient to change only the relevant outer layer.
  • Disadvantages of Clean Architecture

Despite the many advantages provided by Clean Architecture, some disadvantages should also be considered:

  • Learning Curve: Clean Architecture may initially seem complex for developers who are new to layered structures and dependency management. This requires a learning process at the beginning of the project.
  • Initial Cost: Separating layers and managing dependencies at the start of the project may require additional time and effort. However, this investment pays off in the long run.
  • Overengineering for Small Projects: If you are developing a small application or a project with simple business logic, the detailed structure offered by Clean Architecture may be overly complex.
  • Benefits of Clean Architecture to Our Projects:

  • 1. Ensures Code Independence

    One of the fundamental principles of Clean Architecture is that dependencies should always flow from outer layers to inner layers. This approach ensures that the business logic (domain) and business rules are independent of the outside world (database, user interface, APIs, etc.). Thanks to this independence:

  • You Are Not Affected by Database Changes: When you want to change the database or APIs, your business rules or use cases are not affected. For example, if you want to switch from SQL to a NoSQL database, you only need to change the data access code in the outer layer.
  • Easier Testability: Since business logic and business rules are isolated from outer layers, writing unit tests becomes much easier. You can test your business logic without the need for external dependencies like Mock or Stub.

  • 2. Provides Sustainability and Ease of Maintenance

    Clean Architecture increases the sustainability of projects, ensuring that the code remains up-to-date and maintainable for a longer period:

  • Easy to Add New Features: Isolating business logic and use cases in a specific layer allows you to make changes only in the relevant layer when you want to add a new feature or modify an existing one.
  • Reduces Maintenance Costs: The independence of business logic and data access layers reduces the amount of code to maintain. This makes fixing existing bugs or adding new features faster and less costly.
  • Managing Complex Business Rules: Over time, business rules in projects can become complex. Clean Architecture makes managing this complexity easier by isolating business rules in a specific layer.

  • 3. Provides High Flexibility and Reusability

    Clean Architecture makes the different components of your application modular and offers the flexibility to change or reuse them independently:

  • Reusable Business Rules: Layers containing business rules and use cases can be reused in different applications or microservices. This allows similar business logic to be quickly integrated into new projects.
  • Independent Layer Changes: For example, changes made in the user interface layer do not affect the business rules. This allows frontend and backend teams to work independently of each other.
  • Easily Change APIs or Data Sources: When you want to switch to different data sources or third-party services in your application, Clean Architecture allows you to make changes only in the relevant layer, simplifying the transition process.

  • 4. Testability and TDD Compatible

    Clean Architecture prioritizes test writing and supports software development approaches like Test-Driven Development (TDD):

  • Easy Unit Test Writing: Isolating business logic makes it easier to validate business rules with unit tests. For example, to test an "order creation" scenario, you can test the business logic without needing databases or external APIs.
  • Less Complexity for Integration Tests: Tests related to data access or third-party services become more manageable since they are independent of the application layer.
  • High Reliability: Having every part of the code testable reduces the risk of errors being transferred to the production environment and allows you to develop more reliable applications.

  • 5. Manageability in Complex Projects

    When small projects grow and become complex over time, having a structure like Clean Architecture makes managing this complexity easier:

  • Modular Structure: Dividing a large project into parts allows each module to be managed more independently. For example, in an e-commerce application, modules like "Payment" and "Order Management" can be kept in separate layers.
  • Onboarding New Developers: Since the code structure is clearly defined with Clean Architecture, new developers can adapt to the project more quickly and easily.
  • Easier Refactoring: Holding the code in specific layers affects only the relevant layers during refactoring processes, which increases the overall code quality.

  • 6. Ensures Project Longevity

    Clean Architecture allows software projects to adapt to changes over the years and quickly adapt to new technologies:

  • Technology-Independent Structure: Clean Architecture offers a structure without depending on the technologies used. Therefore, even if technologies change, business logic and use cases remain constant.
  • API Changes: Even if new API versions or data storage solutions are used, the business logic of your application is not affected.
  • Ease of Transition to Microservices: Clean Architecture provides a good starting point for transforming monolithic applications into microservice architecture. Each layer can be separated as independent services.

Our Use of Clean Architecture at Negzel Technology Inc. and Reasons for Preference

At Negzel Technology Inc., we strive to adopt modern and sustainable architectural approaches in our software development processes. Clean Architecture is an architectural approach we prefer in our projects that enhances the quality and sustainability of our software projects. I would like to detail why we prefer this architecture, how we implement it, and what it brings to us.

  • Why Do We Prefer Clean Architecture at Negzel Technology Inc.?

    Clean Architecture is an architectural principle that ensures code is more organized, independent, and testable by layering dependencies and isolating business logic from the user interface, database access, and external services. The main reasons we prefer this architecture at Negzel Technology Inc. are:

  • 1. Independent Layers and Flexibility: Clean Architecture ensures that layers in the application are independent of each other. Thanks to this independence, we don't need to touch the business logic when making changes in external dependencies like the database or user interface. This increases flexibility and accelerates the application's adaptation.
  • 2. High Testability: Clean Architecture greatly simplifies the writing of unit tests by ensuring the isolation of business logic. We prioritize test writing to increase the reliability and stability of the applications we develop at Negzel Technology Inc. Thanks to this architecture, we do not need external dependencies like databases or APIs to test business rules.
  • 3. Manageability in Complex Projects: In the projects we develop, business rules and processes can become complex over time. Clean Architecture provides a strong framework to simplify the management of these complex processes. By isolating business rules and use cases in specific layers, we manage complexity.
  • 4. Long-Term Sustainability and Ease of Maintenance: Clean Architecture offers a structure that ensures the long-term sustainability of applications. We want the projects we develop at Negzel Technology Inc. to be long-lasting and maintenance processes to be carried out easily. This architecture ensures that the code is modular and neatly organized, so adding new features or modifying existing ones requires less effort.

  • Advantages Provided by Clean Architecture

    Some important advantages we gain by using Clean Architecture at Negzel Technology Inc. are:

  • 1. High Reliability: Since business logic and data access are separated, errors in the database or third-party services do not affect the overall operation of the application. This allows us to develop more stable and reliable applications.
  • 2. Developer Experience and Teamwork: Clean Architecture allows our developers to take on specific responsibilities and focus on specific layers. The ability of frontend and backend developers to work independently accelerates the development process.
  • 3. Easy Refactoring and Scalability: As the project grows or new features are added, when we need to make adjustments in specific layers, Clean Architecture provides us with easy refactoring. This makes scaling the application and adding new features easier.
  • 4. Preparation for Microservice Transition: Thanks to the modular structure of Clean Architecture, we can transform our monolithic applications into a microservice structure when necessary. Each layer can be separated as an independent microservice.
  • 5. Reuse of Business Rules: The independent structure of business rules and use cases allows them to be reused in different projects. This saves time during the development of new projects and allows the same business rules to be applied in different projects.

  • How Do We Use Clean Architecture at Negzel Technology Inc.?

    While applying the principles and modular structure provided by Clean Architecture in our projects, we separate different layers according to specific responsibilities. We use this structure to make the project more manageable, testable, and sustainable. The layers are defined as follows:

  • 1.Application Layer:
    • This layer is where business processes and use cases are managed.
    • Application logic, services, and Data Transfer Objects (DTOs) reside here.
    • For example, we perform necessary operations here to process a request from a user or to apply business rules.
    • This layer does not have direct communication with the database or external services.
  • 2.Core Layer:
    • This layer is where the domain logic, i.e., business rules and data models, reside.
    • Entity classes, business logic, and domain services are defined here.
    • This innermost layer ensures our projects are flexible and testable by being isolated from the outside world.
  • 3.DependencyInversion Layer:
    • This layer is where Dependency Injection and IoC (Inversion of Control) container settings are configured.
    • It is used to manage dependencies in the project and control the lifecycle of services within the application.
    • For example, we include data access services or external APIs into the application through this layer.
    • This layer allows us to centrally manage dependencies, making it easier to change them.
  • 4.Infrastructure Layer:
    • This layer includes the database access layer, external API calls, and integrations with third-party libraries.
    • Data access to the database is provided using the Repository pattern, and data read/write operations are performed.
    • This layer communicates with the outside world and provides this data to the Application layer.
    • For example, database migrations, data access services, and external API clients are located here.
  • 5.SharedKernel Layer:
    • Common objects that are frequently used throughout the project, not belonging to the domain but usable by multiple layers, are defined here.
    • Exception handling, events, utility classes, and some helper methods are located in this layer.
    • We aim for this layer to be an independent structure that can be reused in other projects or modules.
    • At Negzel Technology Inc., we use SharedKernel to increase reuse and ensure modularity in our projects.
  • 6.Tests Layer:
    • This layer contains unit tests and integration tests in the project.
    • The main purpose of this layer is to enable each layer to be tested independently.
    • In particular, business rules, data access methods, and the operation of services are validated with the tests here.
    • Writing tests is a fundamental part of Clean Architecture to increase our software quality and minimize possible errors.
  • 7.UI Layer:
    • This layer is where the user interface (UI) or API endpoints are defined.
    • It is where requests from the user are handled and directed to the Application layer.
    • API endpoints or MVC structures reside in this layer.
    • We keep the UI layer completely independent to ensure that changes made in the user interface do not affect the business logic.
  • Advantages Provided by Clean Architecture with This Structure

    With this layered structure, we achieve the following advantages at Negzel Technology Inc.:

  • Code Readability and Management: Thanks to layered structures, the responsibility area of each layer is clearly defined. Code readability increases, and developers can navigate the project more comfortably.
  • Modularity and Reusability: Especially with layers like SharedKernel and DependencyInversion, we can define commonly used functionalities in a modular structure and reuse them in different projects.
  • Testability: Since we can independently test the business logic in the Core and Application layers, changes made in business rules do not affect data access or the UI. This allows us to make quick improvements to the project.
  • Easy Maintenance and Refactoring: The independence of the Infrastructure and UI layers from business rules ensures that only the relevant layer needs to be adjusted when changes are required. This simplifies maintenance processes.
  • Dependency Management: By centrally managing dependencies within the project through the DependencyInversion layer, we simplify the integration of new services or external resources.

By fully applying the principles brought by Clean Architecture with this layered structure, we enhance the quality of our projects, quickly adapt to changes, and ensure a sustainable software development process.

Conclusion

Clean Architecture is an architectural approach that stands out by providing independence, sustainability, and flexibility in software projects, isolating business rules from data access and outer layers. In situations where projects grow, need to adapt to new technologies, and business logic changes, Clean Architecture makes the job of developer teams easier. Especially in medium and large-scale projects, it reduces maintenance costs by preserving the orderly and modular structure of the software and extends the project's lifecycle.

By correctly applying Clean Architecture, you can make your software projects more sustainable, manageable, and flexible. This results in outcomes that satisfy both developer teams and customers.

image