{"id":18153215,"url":"https://github.com/agitrubard/hexalayered-architecture","last_synced_at":"2025-10-28T06:31:42.449Z","repository":{"id":259837748,"uuid":"875159782","full_name":"agitrubard/hexalayered-architecture","owner":"agitrubard","description":"Modular, scalable, and maintainable Spring Boot application architecture combining Hexagonal and Layered approaches.","archived":false,"fork":false,"pushed_at":"2024-10-20T19:42:47.000Z","size":491,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-20T12:45:53.332Z","etag":null,"topics":["best-practices","clean-architecture","clean-code","ddd","domain-driven-design","hexagonal-architecture","hexalayered","hexalayered-architecture","java","layered","microservices-architecture","modular-architecture","modular-design","monolith-architecture","software-architecture","software-craftsmanship","spring","spring-boot","tdd","test-driven-development"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agitrubard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-19T08:50:38.000Z","updated_at":"2024-12-19T14:38:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"f9e95545-e670-414c-831f-e77c889b206c","html_url":"https://github.com/agitrubard/hexalayered-architecture","commit_stats":null,"previous_names":["agitrubard/hexalayered-architecture"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agitrubard%2Fhexalayered-architecture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agitrubard%2Fhexalayered-architecture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agitrubard%2Fhexalayered-architecture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agitrubard%2Fhexalayered-architecture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agitrubard","download_url":"https://codeload.github.com/agitrubard/hexalayered-architecture/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238606581,"owners_count":19500014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["best-practices","clean-architecture","clean-code","ddd","domain-driven-design","hexagonal-architecture","hexalayered","hexalayered-architecture","java","layered","microservices-architecture","modular-architecture","modular-design","monolith-architecture","software-architecture","software-craftsmanship","spring","spring-boot","tdd","test-driven-development"],"created_at":"2024-11-02T03:06:03.080Z","updated_at":"2025-10-28T06:31:37.139Z","avatar_url":"https://github.com/agitrubard.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🏛️ HexaLayered Architecture\n\n![](/documents/images/cover.jpg?raw=true)\n\n## Table of Contents\n\n1. [Summary](#summary)\n2. [Architecture Overview](#architecture-overview)\n3. [Layers and Responsibilities](#layers-and-responsibilities)\n    - [Controller Layer](#1-controller-layer)\n    - [Service Layer](#2-service-layer)\n    - [Port/Adapter Layer](#3-portadapter-layer)\n    - [Repository Layer](#4-repository-layer)\n4. [Naming Conventions](#naming-conventions)\n5. [Advantages and Solved Problems](#advantages-and-solved-problems)\n6. [Best Practices](#best-practices)\n7. [Modular Structure](#modular-structure)\n8. [Projects Using HexaLayered Architecture](#projects-using-hexalayered-architecture)\n    - [1. Disaster Management System | AYS APIs](#1-disaster-management-system--ays-apis)\n    - [2. Gelecek Bilimde Community Science Communication Platform APIs](#2-gelecek-bilimde-community-science-communication-platform-apis)\n9. [Contribute](#contribute)\n10. [License](#license)\n11. [FAQ](#faq)\n\n## Summary\n\nHexaLayered Architecture is an innovative architectural approach developed for Spring Boot applications, combining the\nadvantages of Hexagonal (Ports and Adapters) and Layered architectures. This architecture aims to develop scalable and\nsustainable applications by combining modularity and simplicity.\n\nThe name \"HexaLayered\" reflects the combination of two basic architectural approaches:\n\n- **Hexa-**: Comes from Hexagonal Architecture. This architecture aims to isolate the core of the application from the\n  outside world and manage dependencies.\n- **-Layered**: Inspired by the traditional Layered Architecture. This is based on the principle of dividing the\n  application into layers with specific responsibilities.\n\nHexaLayered Architecture offers a flexible, sustainable and understandable architectural solution for modern Spring Boot\napplications.\n\nThis architectural approach:\n\n- Reduces entity addiction\n- Increases modularity\n- Facilitates the implementation of Domain-Driven Design principles\n- Increases testability\n- Limits the impact of changes\n- Facilitates code organization and maintenance\n\nThanks to its modular port, adapter and service structure, it offers the flexibility to independently develop and modify\ndifferent parts of the application. This architecture facilitates the organization and maintenance of code, improves\ntestability, and ensures long-term sustainability, even in large and complex projects.\n\nWhen using HexaLayered Architecture, following the best practices mentioned above will allow you to make the most of the\nadvantages provided by the architecture. Remember that each project may have its own unique requirements and adapt this\narchitecture to the needs of your project when necessary.\n\nThis architectural approach guides software development teams in writing clean, modular and sustainable code. As a\nresult, HexaLayered Architecture offers a powerful architectural solution that supports modern software development\npractices, helping you create scalable and durable applications.\n\n---\n\n## 🌁 Architecture Overview\n\n**HexaLayered Architecture consists of four main layers.\nThese layers communicate with each other through specific interfaces, and each has its own responsibilities.**\n\n![hexalayered-architecture.png](/documents/architecture/hexalayered-architecture.png?raw=true)\n\n---\n\n## 🔐 Layers and Responsibilities\n\n### 1. Controller Layer\n\n**Meets HTTP requests, processes request objects, and returns appropriate response objects.**\n\n- **Package**: `dev.agitrubard.hexalayered.[module].controller`\n- **Input**: Request Object | `TicketCreateRequest`\n- **Output**: Response Object | `TicketResponse`\n- **Communication**: It communicates directly with the Service Layer.\n- **Access Modifier**:\n    - Controller classes should be `package-private`\n\n**Example:**\n\n```java\npackage dev.agitrubard.hexalayered.ticket.controller;\n\n@RestController\nclass TicketController {\n\n    private final TicketCreateService ticketCreateService;\n\n    TicketController(TicketCreateService ticketCreateService) {\n        this.ticketCreateService = ticketCreateService;\n    }\n\n    @PostMapping(\"/api/v1/ticket\")\n    SuccessResponse\u003cTicketResponse\u003e create(@RequestBody TicketCreateRequest request) {\n        Ticket ticket = ticketCreateService.createTicket(request);\n        TicketResponse ticketResponse = TicketToResponseMapper.map(ticket);\n        return SuccessResponse.of(ticket);\n    }\n}\n```\n\n### 2. Service Layer\n\n**Executes business logic, performs necessary validations and performs operations on domain objects.**\n\n- **Package**:\n    - Interface: `dev.agitrubard.hexalayered.[module].service`\n    - Implementation: `dev.agitrubard.hexalayered.[module].service.impl`\n- **Input**: Request Object or specific wrapper objects | `TicketCreateRequest` or `Long` or `String` etc.\n- **Output**: Domain Object or specific wrapper objects | `Ticket` or `Long` or `String` etc.\n- **Communication**:\n    - The service interface is called by the Controller.\n    - ServiceImpl communicates with the Port/Adapter Layer using Port interfaces.\n- **Access Modifier**:\n    - Service interfaces should be `public`\n    - Service implementation classes should be `package-private`\n\n**Example:**\n\n```java\npackage dev.agitrubard.hexalayered.ticket.service;\n\npublic interface TicketCreateService {\n    Ticket create(TicketCreateRequest request);\n}\n```\n\n```java\npackage dev.agitrubard.hexalayered.ticket.service.impl;\n\nclass TicketCreateServiceImpl implements TicketCreateService {\n\n    private final TicketSavePort ticketSavePort;\n\n    TicketCreateServiceImpl(TicketSavePort ticketSavePort) {\n        this.ticketSavePort = ticketSavePort;\n    }\n\n    @Override\n    public Ticket create(TicketCreateRequest request) {\n        Ticket ticket = new Ticket(request.getTitle(), request.getDescription());\n        return ticketSavePort.saveTicket(ticket);\n    }\n}\n```\n\n### 3. Port/Adapter Layer\n\n**Provides communication with external systems, converts domain objects into formats that external systems can\nunderstand\nand does the opposite.**\n\n- **Package**:\n    - Port: `dev.agitrubard.hexalayered.[module].port`\n    - Adapter: `dev.agitrubard.hexalayered.[module].port.adapter`\n- **Input**: Domain Object or specific wrapper objects | `Ticket` or `Long` or `String` etc.\n- **Output**: Domain Object or specific wrapper objects | `Ticket` or `Long` or `String` etc.\n- **Communication**:\n    - Port interfaces are called by service implementations\n    - Adapters (port implementations) communicate with the repository layer.\n- **Access Modifier**:\n    - Port interfaces should be `public`\n    - Adapter classes should be `package-private`\n\n**Example:**\n\n```java\npackage dev.agitrubard.hexalayered.ticket.port;\n\npublic interface TicketSavePort {\n\n    Ticket save(Ticket ticket);\n\n}\n```\n\n```java\npackage dev.agitrubard.hexalayered.ticket.port.adapter;\n\nclass TicketSaveAdapter implements TicketSavePort {\n\n    private final TicketRepository ticketRepository;\n\n    TicketSaveAdapter(TicketRepository ticketRepository) {\n        this.ticketRepository = ticketRepository;\n    }\n\n    @Override\n    public Ticket save(Ticket ticket) {\n        TicketEntity entity = TicketToEntityMapper.map(ticket);\n        TicketEntity savedEntity = ticketRepository.save(entity);\n        return TicketEntityToDomainMapper.map(savedEntity);\n    }\n}\n```\n\n### 4. Repository Layer\n\n**Performs database operations, manages CRUD operations on entity objects.**\n\n- **Paket**: `dev.agitrubard.hexalayered.[module].repository`\n- **Input**: Entity Object or specific wrapper objects | `TicketEntity` or `Long` or `String` etc.\n- **Output**: Entity Object or specific wrapper objects | `TicketEntity` or `Long` or `String` etc.\n- **Communication**: Called by adapters (port implementations).\n- **Access Modifier**:\n    - Repository interfaces should be `public`\n\n**Example:**\n\n```java\npackage dev.agitrubard.hexalayered.ticket.repository;\n\npublic interface TicketRepository extends JpaRepository\u003cTicketEntity, Long\u003e {\n}\n```\n\n---\n\n## 📝 Naming Conventions\n\n1. **Controller**:\n    - Package: `dev.agitrubard.hexalayered.[module].controller`\n    - Class: `[Domain]Controller` | `TicketController`, `InstitutionController`\n\n2. **Service**:\n    - Package:\n        - Interface Package: `dev.agitrubard.hexalayered.[module].service`\n        - Implementation Package: `dev.agitrubard.hexalayered.[module].service.impl`\n    - Interface: `[Domain][Action]Service` | `TicketCreationService`, `InstitutionUpdateService`\n    - Implementation: `[Domain][Action]ServiceImpl` | `TicketCreationServiceImpl`, `InstitutionUpdateServiceImpl`\n\n3. **Port \u0026 Adapter**:\n    - Package:\n        - Interface Package: `dev.agitrubard.hexalayered.[module].port`\n        - Implementation Package: `dev.agitrubard.hexalayered.[module].port.adapter`\n    - Interface: `[Domain][Action]Port` | `TicketSavePort`, `InstitutionReadPort`\n    - Implementation: `[Domain][Action]Adapter` | `TicketSaveAdapter`, `InstitutionReadAdapter`\n\n4. **Repository**:\n    - Package: `dev.agitrubard.hexalayered.[module].repository`\n    - Interface: `[Domain]Repository` | `TicketRepository`, `InstitutionRepository`\n\n5. **Domain Model**:\n    - Package: `dev.agitrubard.hexalayered.[module].model`\n    - Class: `[Domain]` | `Ticket`, `Institution`\n\n6. **Entity**:\n    - Package: `dev.agitrubard.hexalayered.[module].model.entity`\n    - Class: `[Domain]Entity` | `TicketEntity`, `InstitutionEntity`\n\n7. **Request**:\n    - Package: `dev.agitrubard.hexalayered.[module].model.request`\n    - Class: `[Domain][Action]Request` | `TicketCreateRequest`, `InstitutionUpdateRequest`\n\n8. **Response**:\n    - Package: `dev.agitrubard.hexalayered.[module].model.response`\n    - Class: `[Domain]Response` or `[Domain][Action]Response` | `TicketResponse`, `InstitutionResponse`\n\n9. **Exception**:\n    - Package: `dev.agitrubard.hexalayered.[module].exception`\n    - Class: `[ErrorAction]Exception` | `TicketNotFoundByIdException`\n\n10. **Util**:\n\n- Package: `dev.agitrubard.hexalayered.[module].util`\n- Class: `[Name]Util` or `[Name][Action]Util` or `[Domain][Action]` | `FileUtil` or `FileReadUtil` or `\n  TicketCodeGenerator`\n\n---\n\n## 🚀 Advantages and Solved Problems\n\n**1. Reducing Entity Dependency**:\n\n- By highlighting the use of domain objects, it prevents the use of entity objects throughout the application.\n- Entity objects cannot leave the adapter layer, so the rest of the application is not affected when the database\n  structure changes.\n\n**2. Modularity and Insulation**:\n\n- Each module is independent in itself and isolated from other modules.\n- Changes only affect the relevant module, other modules are not affected.\n\n**3. Modular Port, Adapter and Service Structure**:\n\n- Separate port, adapter and service classes can be created for each function.\n- This structure supports the Single Responsibility Principle (SRP) and reduces code repetition.\n\n**4. Clean Architecture**:\n\n- Clearly separates the inner and outer layers.\n- Dependencies are from the inside out, the outer layers are not dependent on the inner layers.\n\n**5. Easy Testability**:\n\n- Each layer can be tested independently.\n- Isolated tests can be written using mock objects.\n\n**6. DDD Compliance**:\n\n- Facilitates the implementation of Domain-Driven Design principles.\n- Domain objects are located in the center of the application.\n\n**7. Flexibility and Interchangeability**:\n\n- Interaction with external systems can be easily changed via Port/Adapter Layer.\n- It is easier to add new features or change existing features.\n\n---\n\n## 🎯 Best Practices\n\n1. **Layer Insulation**: Ensure that each layer fulfills its responsibility and is isolated from the details of the\n   other layers.\n2. **Centrality of Domain Objects**: Put domain objects in the center of the application and execute business logic over\n   these objects.\n3. **Dependency Injection**: Use Dependency Injection (DI) to manage interlayer dependencies.\n4. **Naming Consistency**: Sticky adhere to the specified naming standards. This facilitates the readability and\n   maintenance of the code.\n5. **Protecting the Modular Structure**: Make each module independent in itself. Keep inter-module dependencies to a\n   minimum.\n6. **Port and Adapter Separation**: Create a separate adapter for each port. This makes it easy to switch between\n   different implementations.\n7. **Service Modularity**: Design the services in a thin modular structure with a single responsibility.\n8. **Exception Handling**: Create custom exception classes for each layer and manage them appropriately.\n9. **Validation**: Perform business rule validations in the service layer and input validations in the controller layer.\n10. **Mapper Usage**: Use dedicated mapper classes for object transformations between different layers.\n11. **Immutable Objects**: Use immutable objects as much as possible, especially for domain objects.\n12. **Documentation**: Provide adequate documentation for each module, service and important class.\n\n---\n\n## 📦 Modular Structure\n\nHexaLayered Architecture divides the application into modules according to different business domains. Each module\ncontains the above-mentioned layers.\n\nBelow is an example of an application structure that includes the Common, Ticket and Institution modules:\n\n```\ndev.agitrubard.hexalayered\n├── common\n│   │\n│   ├── configuration\n│   │   └── DataSourceConfiguration\n│   │\n│   ├── exception\n│   │   ├── handler\n│   │   │   └── GlobalExceptionHandler\n│   │   ├── AbstractNotFoundException\n│   │   ├── AbstractServerException\n│   │   └── FileReadException\n│   │\n│   ├── model\n│   │   ├── entity\n│   │   │   └── BaseEntity\n│   │   ├── mapper\n│   │   │   └── BaseMapper\n│   │   ├── response\n│   │   │   ├── ErrorResponse\n│   │   │   └── SuccessResponse\n│   │   └── BaseDomainModel\n│   │\n│   └── util\n│       ├── FileUtil\n│       └── ListUtil\n│\n│\n├── ticket\n│   │\n│   ├── controller\n│   │   └── TicketController\n│   │\n│   ├── exception\n│   │   └── TicketNotFoundByIdException\n│   │\n│   ├── service\n│   │   ├── TicketCreateService\n│   │   ├── TicketUpdateService\n│   │   ├── TicketDeleteService\n│   │   └── impl\n│   │       ├── TicketCreateServiceImpl\n│   │       ├── TicketUpdateServiceImpl\n│   │       └── TicketDeleteServiceImpl\n│   │\n│   ├── port\n│   │   ├── TicketSavePort\n│   │   ├── TicketReadPort\n│   │   ├── TicketDeletePort\n│   │   └── adapter\n│   │       ├── TicketSaveAdapter\n│   │       ├── TicketReadAdapter\n│   │       └── TicketDeleteAdapter\n│   │\n│   ├── repository\n│   │   └── TicketRepository\n│   │\n│   ├── model\n│   │   ├── entity\n│   │   │   └── TicketEntity\n│   │   ├── enums\n│   │   │   └── TicketStatus\n│   │   ├── mapper\n│   │   │   ├── TicketToEntityMapper\n│   │   │   └── TicketEntityToDomainMapper\n│   │   ├── request\n│   │   │   ├── TicketCreateRequest\n│   │   │   └── TicketUpdateRequest\n│   │   ├── response\n│   │   │   └── TicketResponse\n│   │   └── Ticket\n│   │\n│   └── util\n│       └── TicketCodeGenerator\n│\n│\n└── institution\n    │\n    ├── controller\n    │   └── InstitutionController\n    │\n    ├── exception\n    │   ├── InstitutionAlreadyExistByNameException\n    │   └── InstitutionNotFoundByIdException\n    │\n    ├── service\n    │   ├── InstitutionService\n    │   └── impl\n    │       └── InstitutionServiceImpl\n    │\n    ├── port\n    │   ├── InstitutionSavePort\n    │   ├── InstitutionReadPort\n    │   ├── InstitutionDeletePort\n    │   └── adapter\n    │       └── InstitutionAdapter\n    │\n    ├── repository\n    │   └── InstitutionRepository\n    │\n    └── model\n        ├── entity\n        │   └── InstitutionEntity\n        ├── enums\n        │   └── InstitutionStatus\n        ├── mapper\n        │   ├── InstitutionToEntityMapper\n        │   └── InstitutionEntityToDomainMapper\n        ├── request\n        │   ├── InstitutionCreateRequest\n        │   └── InstitutionUpdateRequest\n        ├── response\n        │   └── InstitutionResponse\n        └── Institution\n```\n\n---\n\n## Projects Using HexaLayered Architecture\n\nYou can explore the following open-source projects to see real-world applications of HexaLayered Architecture:\n\n### 1. Disaster Management System | AYS APIs\n\n**This project demonstrates how HexaLayered Architecture is implemented in complex and critical systems.**\n\nhttps://github.com/afet-yonetim-sistemi/ays-be\n\n- Modular structure\n- End-to-end error handling\n- Extended search and filtering capabilities\n- Comprehensive testing infrastructure\n- Advanced security and authorization features\n\n### 2. Gelecek Bilimde Community Science Communication Platform APIs\n\nThis project showcases how HexaLayered Architecture is used in content management and API design.\n\nhttps://github.com/gelecekbilimde/backend\n\n- Modular structure\n- End-to-end error handling\n- Extended search and filtering capabilities\n- Security and authorization features\n\nThese projects demonstrate how HexaLayered Architecture is applied in different use cases. As both projects are\nopen-source, you can examine their code and see detailed practical applications of the architecture.\n\n\u003e If you have developed a project using HexaLayered Architecture and would like it listed here, please let us know!\n\n---\n\n## 🧑‍💻 Contribute\n\nWe can work together to develop and improve HexaLayered Architecture. You can review\nthe [CONTRIBUTING.md](CONTRIBUTING.md) file to contribute.\n\n---\n\n## 🪪 License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n---\n\n## ❓ FAQ\n\n**1. How can I integrate HexaLayered Architecture into my current project?**\n\n```\nYou can progressively migrate your current project to HexaLayered Architecture. Start by developing new modules with\nthis architecture, and gradually transform existing modules over time. Begin with the most isolated parts of your\napplication and work your way towards more integrated components.\n```\n\n**2. Is HexaLayered Architecture compatible with microservices architecture?**\n\n```\nYes, HexaLayered Architecture is highly compatible with microservices. Each microservice can implement the HexaLayered\nArchitecture internally, providing a consistent structure across your microservices ecosystem while maintaining loose\ncoupling between services.\n```\n\n**3. How does HexaLayered Architecture improve testability?**\n\n```\nHexaLayered Architecture improves testability by clearly separating concerns and dependencies. Each layer can be tested\nin isolation using mocks or stubs for its dependencies. This allows for more focused unit tests, easier integration\ntests, and overall better test coverage.\n```\n\n**4. What's the difference between Ports and Adapters in this architecture?**\n\n```\nPorts are interfaces that define how the application interacts with external systems or how external systems interact\nwith the application. Adapters are the concrete implementations of these interfaces. This separation allows for easy\nswapping of implementations without changing the core business logic.\n```\n\n**5. How do I handle cross-cutting concerns in HexaLayered Architecture?**\n\n```\nCross-cutting concerns like logging, security, and transaction management can be handled using aspects (AOP) or by\nimplementing these concerns in the appropriate layers. For example, security checks can be done in the Controller layer,\nwhile transaction management might be handled in the Service layer.\n```\n\n**6. Can I use HexaLayered Architecture with other frameworks besides Spring Boot?**\n\n```\nWhile the examples provided are in Spring Boot, the principles of HexaLayered Architecture are framework-agnostic. You\ncan apply this architecture to projects using other frameworks or even in different programming languages, adapting the\nimplementation details as necessary.\n```\n\n**7. How does HexaLayered Architecture support Domain-Driven Design (DDD)?**\n\n```\nHexaLayered Architecture aligns well with DDD principles. The domain model remains at the core of the application,\nisolated from external concerns. The Port and Adapter layers help in creating a clear boundary between the domain and\ninfrastructure, which is a key aspect of DDD.\n```\n\n**8. What are the performance implications of using HexaLayered Architecture?**\n\n```\nGenerally, the performance impact of HexaLayered Architecture is minimal. While it may introduce a slight overhead due\nto additional layers and mappings, the benefits in terms of maintainability and flexibility usually outweigh this.\nProper implementation and optimization can mitigate most performance concerns.\n```\n\n**9. How do I handle database transactions across multiple services in HexaLayered Architecture?**\n\n```\nFor transactions spanning multiple services, you can use distributed transaction management techniques like the Saga\npattern or two-phase commit protocol. Alternatively, you might reconsider your domain boundaries to minimize the need\nfor cross-service transactions.\n```\n\n**10. Is HexaLayered Architecture suitable for small projects?**\n\n```\nWhile HexaLayered Architecture shines in medium to large projects, it might be overkill for very small applications.\nHowever, if you anticipate your project growing in complexity, starting with this architecture can set a solid\nfoundation for future expansion.\n```\n\n**11. How do I manage dependencies between different modules in HexaLayered Architecture?**\n\n```\nDependencies between modules should be managed through well-defined interfaces. If one module needs functionality from\nanother, this should be exposed through a port (interface) and accessed via an adapter. This maintains the modularity\nand allows for easier changes in the future.\n```\n\n**12. Can I use HexaLayered Architecture with event-driven systems?**\n\n```\nYes, HexaLayered Architecture works well with event-driven systems. Events can be treated as a type of port, with\nadapters handling the publishing and subscribing to these events. This allows the core domain logic to remain isolated\nfrom the specifics of the event system being used.\n```\n\n**13. If I don't have a very comprehensive service, should I still separate it according to tasks like Read, Write?**\n\n```\nIt depends on the complexity and potential growth of your service. For simpler services, it's often acceptable to keep\nread and write operations in a single service class. However, if you anticipate that the service might grow in\ncomplexity or if you want to maintain consistency with larger services in your project, separating them can be\nbeneficial.\n\nKey considerations:\n- If the service has distinct read and write logic that doesn't overlap significantly, separation might be cleaner.\n- If you foresee the service growing more complex in the future, early separation can make future changes easier. \n- For very simple CRUD operations, a single service might be more pragmatic.\n- Consistency across your project is important. If other services are separated, maintaining the same pattern could be\nbeneficial for developer familiarity.\n\nRemember, the goal is to balance clean architecture principles with practical development needs. It's okay to start with\na single service and refactor later if needed.\n```\n\n**14. If I don't have a very comprehensive port/adapter,\nshould I still separate it according to tasks like Read, Write?**\n\n```\nSimilar to services, the decision to separate ports and adapters depends on the complexity of the operations and the\npotential for future growth. \n\nHere are some guidelines:\n- For simple CRUD operations, a single port/adapter pair might be sufficient. For example, a TicketPort and TicketAdapter\ncould handle all basic operations.\n- If read and write operations have significantly different concerns (e.g., different external systems, caching\nstrategies, or transaction requirements), separation might be beneficial.\n- Consider the Single Responsibility Principle. If read and write operations have distinct responsibilities or might\nevolve independently, separating them could make the code more maintainable.\n- Think about testing: if separating read and write operations would make your tests cleaner and more focused, it might be\nworth doing.\n- Consider the consistency with your service layer. If you've separated your services into read and write, it might make\nsense to reflect this in your ports and adapters.\n\nUltimately, the decision should be based on your specific use case, the complexity of your domain, and your team's\npreferences. It's perfectly acceptable to start with a single port/adapter and refactor later if the need arises. The\nkey is to keep your code organized, maintainable, and aligned with your project's overall architecture.\n```\n\n**15. How do I decide when to create separate classes for different operations versus keeping them in one class?**\n\n```\nThis decision applies to both services and ports/adapters.\n\nConsider the following factors:\n1. Complexity: If the logic for different operations (e.g., read, write, update) is complex and distinct, separate classes\nmight be clearer.\n2. Size: If a single class is becoming too large (e.g., over 300 lines), it might be time to split it.\n3. Change frequency: If certain operations change more frequently than others, separating them can isolate changes.\n4. Reusability: If some operations are reused across different contexts, separating them can promote code reuse.\n5. Team structure: If different team members or teams are responsible for different operations, separation can help with\nparallel development.\n6. Performance: In some cases, separating read and write operations can help with optimizing each for its specific needs (\ne.g., read optimization vs. write consistency).\n\nRemember, the goal of HexaLayered Architecture is to create a clean, maintainable, and flexible codebase. The level of\ngranularity should serve this goal without introducing unnecessary complexity.\n```\n\n**16. Should I always create interfaces? What happens if I don't create an interface?**\n\n```\nIn HexaLayered Architecture, interfaces should be used for communication between all layers.\nThis approach should be applied regardless of perceived immediate need.\n\nThe reasons are:\n1. Abstraction: Interfaces provide a layer of abstraction independent of implementation.\n2. Flexibility: Allows for future changes and different implementations.\n3. Testability: Facilitates easy creation of mock objects.\n4. Dependency Management: Reduces dependencies between layers.\n5. Architectural Consistency: Creates a consistent communication structure across all layers.\n\nNot using interfaces would result in losing these advantages and deviating from the core principles of the architecture. For the success of HexaLayered Architecture, the use of interfaces between all layers is critical.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagitrubard%2Fhexalayered-architecture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagitrubard%2Fhexalayered-architecture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagitrubard%2Fhexalayered-architecture/lists"}