diff --git a/roadmaps/software-design-architecture/content/abstract-classes@RMkEE7c0jdVFqZ4fmjL6Y.md b/roadmaps/software-design-architecture/content/abstract-classes@RMkEE7c0jdVFqZ4fmjL6Y.md index dd5247200..1d4ff13b1 100644 --- a/roadmaps/software-design-architecture/content/abstract-classes@RMkEE7c0jdVFqZ4fmjL6Y.md +++ b/roadmaps/software-design-architecture/content/abstract-classes@RMkEE7c0jdVFqZ4fmjL6Y.md @@ -1,8 +1,6 @@ # Abstract Classes -An abstract class is a class in object-oriented programming (OOP) that cannot be instantiated. Instead, it serves as a template or blueprint for other classes to inherit from. An abstract class can contain both abstract and non-abstract methods (abstract methods are methods that do not have any implementation, they just have a signature). - -Abstract classes are used to provide a common interface and implementation for a group of related classes. They are also used to define common behavior that must be implemented by all subclasses. A subclass that inherits from an abstract class is called a concrete class, and it must provide an implementation for all the abstract methods declared in the parent class. +An abstract class is a restricted base class that cannot be used to create objects. It serves as a blueprint for other classes, providing a common structure by defining methods that subclasses must implement. While it can contain fully functional methods, its primary purpose is to enforce a consistent interface and shared behavior across related objects in a system. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/abstraction@VA8FMrhF4non9x-J3urY8.md b/roadmaps/software-design-architecture/content/abstraction@VA8FMrhF4non9x-J3urY8.md index 38cc50746..a5a3e7d35 100644 --- a/roadmaps/software-design-architecture/content/abstraction@VA8FMrhF4non9x-J3urY8.md +++ b/roadmaps/software-design-architecture/content/abstraction@VA8FMrhF4non9x-J3urY8.md @@ -1,11 +1,6 @@ # Abstraction -Abstraction is a concept in object-oriented programming (OOP) that refers to the process of hiding the implementation details of an object and exposing only its essential features. It enables the use of objects without the need to understand the underlying complexity of their internal structure and behavior. - -There are two types of abstraction: - -* Data abstraction: refers to hiding the internal representation of data and providing a simplified view of the data through a set of well-defined interfaces. -* Behavioral abstraction: refers to hiding the internal behavior of an object and providing a simplified view of its capabilities through a set of well-defined interfaces. +Abstraction is the process of hiding complex implementation details and showing only the essential features of an object to the user. It allows developers to interact with a simplified interface while the underlying logic remains encapsulated and separate. By focusing on what an object does rather than how it achieves its tasks, abstraction reduces programming complexity and prevents unnecessary exposure of internal operations. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/anemic-models@nVaoI4IDPVEsdtFcjGNRw.md b/roadmaps/software-design-architecture/content/anemic-models@nVaoI4IDPVEsdtFcjGNRw.md index 0967b813a..263892971 100644 --- a/roadmaps/software-design-architecture/content/anemic-models@nVaoI4IDPVEsdtFcjGNRw.md +++ b/roadmaps/software-design-architecture/content/anemic-models@nVaoI4IDPVEsdtFcjGNRw.md @@ -1,8 +1,6 @@ # Anemic Models -An Anemic model, also known as an anemic domain model, is a type of domain model in which the domain objects only contain data (attributes) and lack behavior. An anemic model often results in the use of data-transfer objects (DTOs) and service layer to handle the behavior. - -An anemic model is considered an anti-pattern in object-oriented programming (OOP) because it violates the principles of encapsulation and separation of concerns. In an anemic model, the behavior is separated from the data, and is typically implemented in a separate service layer, which can lead to a complex, tightly coupled, and hard-to-maintain codebase. +Anemic models are domain objects that contain little or no business logic, acting primarily as simple data holders with public getters and setters. In this design, the actual behavior and decision-making logic are placed in separate service classes, which interact with the data objects to perform operations. While this approach separates data from logic, it often leads to a procedural style of programming where the richness of the domain model is lost and the responsibility for maintaining data integrity is shifted to external services. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/architectural-patterns@gJYff_qD6XS3dg3I-jJFK.md b/roadmaps/software-design-architecture/content/architectural-patterns@gJYff_qD6XS3dg3I-jJFK.md index 1c935252c..1e8e74123 100644 --- a/roadmaps/software-design-architecture/content/architectural-patterns@gJYff_qD6XS3dg3I-jJFK.md +++ b/roadmaps/software-design-architecture/content/architectural-patterns@gJYff_qD6XS3dg3I-jJFK.md @@ -1,3 +1,3 @@ # Architectural Patterns -Architectural patterns are high-level structural templates that shape the overall organization of a system, such as layered architecture, microservices, event-driven, and serverless. They define how major components communicate and scale, and are chosen based on the problem domain, team, and operational requirements. +Architectural patterns are high-level structural templates that shape the overall organization of a system, such as layered architecture, microservices, event-driven, and serverless. They define how major components communicate and scale, and are chosen based on the problem domain, team, and operational requirements. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/architectural-patterns@jq916t7svaMw5sFOcqZSi.md b/roadmaps/software-design-architecture/content/architectural-patterns@jq916t7svaMw5sFOcqZSi.md index 161af6280..91cbac619 100644 --- a/roadmaps/software-design-architecture/content/architectural-patterns@jq916t7svaMw5sFOcqZSi.md +++ b/roadmaps/software-design-architecture/content/architectural-patterns@jq916t7svaMw5sFOcqZSi.md @@ -1,18 +1,6 @@ # Architectural Patterns -Architectural patterns are a set of solutions that have been proven to work well for specific types of software systems. They provide a common vocabulary and set of best practices for designing and building software systems, and can help developers make better design decisions. Some common architectural patterns include: - -* Model-View-Controller (MVC): A pattern for separating the user interface, business logic, and data storage components of a system. -* Microservices: A pattern for building systems as a collection of small, independently deployable services that communicate over a network. -* Event-Driven: A pattern for building systems that respond to events and perform actions in response. -* Layered: A pattern for organizing a system into layers, with each layer providing a specific set of services to the layer above it. -* Pipe-and-Filter: A pattern for building systems as a series of independent, reusable processing elements that are connected together in a pipeline. -* Command-Query Responsibility Segregation (CQRS): A pattern for separating the handling of commands (which change the state of the system) from the handling of queries (which retrieve information from the system) -* Blackboard: A pattern for creating a centralized repository of information that can be accessed and modified by multiple independent modules or subsystems. -* Microkernel: A pattern that aims to minimize the amount of code running in kernel mode and move as much functionality as possible into user-mode processes. -* Serverless: A design pattern that allows developers to build and run applications and services without having to provision and manage servers. -* Message Queues and Streams: A pattern that decouples different components of a system and enables asynchronous communication between them. -* Event Sourcing: A pattern that stores all changes to the system's state as a sequence of events, rather than just the current state. +Architectural patterns are reusable solutions to common problems encountered during the high-level design of software systems. They provide a structural template that defines how components within an application interact, organize, and communicate. These patterns serve as a blueprint to ensure software remains scalable, maintainable, and efficient by establishing clear boundaries and responsibilities for different parts of the system. Common examples include Model-View-Controller, microservices, and layered architectures, each offering specific strategies for managing complexity and data flow. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/architectural-principles@dBq7ni-of5v1kxpdmh227.md b/roadmaps/software-design-architecture/content/architectural-principles@dBq7ni-of5v1kxpdmh227.md index bcb21eccb..0a1e99cc2 100644 --- a/roadmaps/software-design-architecture/content/architectural-principles@dBq7ni-of5v1kxpdmh227.md +++ b/roadmaps/software-design-architecture/content/architectural-principles@dBq7ni-of5v1kxpdmh227.md @@ -1,3 +1,3 @@ # Architectural Principles -Architectural principles are fundamental rules that guide design decisions across a system, such as loose coupling, high cohesion, separation of concerns, and scalability. They are the "why" behind a structure, helping teams make consistent trade-offs and evolve software without reworking its foundations. +Architectural principles are a set of fundamental guidelines and best practices used to inform the structural design of a software system. These rules provide a foundation for making consistent decisions regarding the organization of code, the interaction between components, and the management of data flow. By adhering to these concepts, developers can ensure that a system remains modular, scalable, and easier to maintain over time. These principles help teams establish a common technical language and prevent structural decay as an application grows in complexity. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/architectural-styles@37xWxG2D9lVuDsHUgLfzP.md b/roadmaps/software-design-architecture/content/architectural-styles@37xWxG2D9lVuDsHUgLfzP.md index d5f28a440..d3b2c8ab6 100644 --- a/roadmaps/software-design-architecture/content/architectural-styles@37xWxG2D9lVuDsHUgLfzP.md +++ b/roadmaps/software-design-architecture/content/architectural-styles@37xWxG2D9lVuDsHUgLfzP.md @@ -1,6 +1,6 @@ # Architectural Styles -Architectural styles are sets of principles and constraints that define the characteristics of a software system. They provide a vocabulary and a framework for describing common system properties such as structure, behavior, and interaction. These styles act as blueprints, offering reusable solutions to recurring design problems and guiding the organization of components and their relationships within a software architecture. Examples of architectural styles include layered architecture, microservices, and event-driven architecture, each with its own strengths and weaknesses that make it suitable for specific scenarios. +Architectural styles are established approaches to organizing the high level structure of a software system, such as how components are distributed, how they communicate, and how they are deployed. Each style, like layered, client-server, or microservices, comes with its own trade-offs around scalability, maintainability, and complexity. Choosing a style shapes many later decisions in a project, including deployment strategy, team structure, and technology choices. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/architectural-styles@En_hvwRvY6k_itsNCQBYE.md b/roadmaps/software-design-architecture/content/architectural-styles@En_hvwRvY6k_itsNCQBYE.md index 10dca5972..c9323bc1a 100644 --- a/roadmaps/software-design-architecture/content/architectural-styles@En_hvwRvY6k_itsNCQBYE.md +++ b/roadmaps/software-design-architecture/content/architectural-styles@En_hvwRvY6k_itsNCQBYE.md @@ -1,16 +1,6 @@ # Architectural Styles -Architectural styles in software refer to the overall design and organization of a software system, and the principles and patterns that are used to guide the design. These styles provide a general framework for the design of a system, and can be used to ensure that the system is well-structured, maintainable, and scalable. - -Some common architectural styles in software include: - -* Microservices: where the system is built as a collection of small, independent, and loosely-coupled services. -* Event-Driven: where the system reacts to specific events that occur, rather than being continuously polled for changes. -* Layered: where the system is divided into a set of layers, each of which has a specific responsibility and communicates with the other layers through well-defined interfaces. -* Service-Oriented: where the system is built as a collection of services that can be accessed over a network. -* Data-Centric: where the system is focused on the storage, retrieval and manipulation of data, rather than the processing of data. -* Component-Based: where the system is composed of reusable and independent software components. -* Domain-Driven: where the system is organized around the core business domain and business entities. +Architectural styles are high-level patterns that define the fundamental structure and organization of a software system. They provide a standardized way to arrange components, define their responsibilities, and establish the communication mechanisms between them. By selecting a specific style, such as microservices, layered architecture, or event-driven design, developers determine how data flows through the application and how the system scales over time. These styles serve as blueprints that guide technical decisions, ensuring the software remains modular, maintainable, and aligned with its functional requirements. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/avoid-passing-nulls-booleans@yyKvmutbxu3iVHTuqr5q4.md b/roadmaps/software-design-architecture/content/avoid-passing-nulls-booleans@yyKvmutbxu3iVHTuqr5q4.md index 1ad23bbcf..7b2c44669 100644 --- a/roadmaps/software-design-architecture/content/avoid-passing-nulls-booleans@yyKvmutbxu3iVHTuqr5q4.md +++ b/roadmaps/software-design-architecture/content/avoid-passing-nulls-booleans@yyKvmutbxu3iVHTuqr5q4.md @@ -1,11 +1,3 @@ -# Avoid Passing Nulls Booleans +# Avoiding Nulls and Booleans as Arguments -Passing nulls or Booleans can lead to unexpected behavior and difficult-to-debug errors in a program. Here are some ways to avoid passing nulls or Booleans in system architecture: - -* Use Optionals or Maybe types instead of nulls to indicate the absence of a value. This makes it clear when a value is missing and prevents null reference exceptions. -* Use a default value for function arguments instead of allowing them to be null or Boolean. This eliminates the need to check for null or Boolean values and reduces the potential for errors. -* Use the Null Object pattern to replace null values with a special object that has a defined behavior. This eliminates the need to check for null values and makes the code more readable. -* Use the Ternary operator (?:) instead of if-else statements when working with Booleans. This can make the code more concise and easier to read. -* Use the assert function to check the validity of function arguments and throw an exception if they are invalid. - -By following these best practices, the system architecture will be more robust and less error-prone. \ No newline at end of file +Passing null values or boolean flags into functions often leads to code that is difficult to understand and prone to errors. When a function accepts a boolean, it frequently signals that the function is doing too many things at once, violating the single responsibility principle. Similarly, passing null values forces developers to include repetitive conditional checks to prevent runtime crashes. Instead of using these markers, developers should decompose complex functions into smaller, specific methods or utilize specialized objects and patterns to handle different execution paths clearly. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/boundaries@-Kw8hJhgQH2qInUFj2TUe.md b/roadmaps/software-design-architecture/content/boundaries@-Kw8hJhgQH2qInUFj2TUe.md index adfab902e..5af7a03ac 100644 --- a/roadmaps/software-design-architecture/content/boundaries@-Kw8hJhgQH2qInUFj2TUe.md +++ b/roadmaps/software-design-architecture/content/boundaries@-Kw8hJhgQH2qInUFj2TUe.md @@ -1,8 +1,6 @@ # Boundaries -In software architecture, boundaries refer to the interfaces or the points of separation between different components or systems. These boundaries can be physical, such as between different microservices in a distributed system, or logical, such as between different layers in an application. - -Boundaries are important because they define the points of interaction between different components or systems, and they dictate how those components or systems will communicate with each other. By defining clear boundaries, it makes it easier to understand, test, and maintain the system, as the interactions between components or systems are well-defined and easy to reason about. +Boundaries define the separation between different parts of a system, marking where one component's responsibility ends and another's begins. They control how data and control flow between modules, layers, or services, and they hide internal implementation details behind a stable interface. Clear boundaries let teams change the internals of one part of a system without affecting the others, which supports independent development and testing. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/class-variants@c6n-wOHylTbzpxqgoXtdw.md b/roadmaps/software-design-architecture/content/class-variants@c6n-wOHylTbzpxqgoXtdw.md index 6096becbe..78ed9bb86 100644 --- a/roadmaps/software-design-architecture/content/class-variants@c6n-wOHylTbzpxqgoXtdw.md +++ b/roadmaps/software-design-architecture/content/class-variants@c6n-wOHylTbzpxqgoXtdw.md @@ -1,8 +1,6 @@ -# Class Invariants +# Class Variants -A class invariant is a set of conditions that must be true for any object of a class, at any point in time. In object-oriented programming (OOP), class invariants are used to define the valid states of an object and to ensure that the object always remains in a valid state. - -Class invariants are typically defined in the constructor of a class and are enforced through the use of private methods and data members that are used to validate the state of the object. They are also checked in the class's methods before and after any operation that can change the state of the object. +Class variants are a conceptual approach within object-oriented design used to represent different forms or specialized versions of an entity while maintaining a shared core identity. This technique involves defining a base structure that establishes common attributes and behaviors, which are then extended or modified to support specific functional requirements or domain constraints. By organizing classes into hierarchies or specific groupings based on these variations, developers can manage complexity and ensure that the system remains modular as new types of objects are introduced. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/clean-code@TJZgsxpfOmltUUChMzlEM.md b/roadmaps/software-design-architecture/content/clean-code@TJZgsxpfOmltUUChMzlEM.md index 6fc81426c..170ca614b 100644 --- a/roadmaps/software-design-architecture/content/clean-code@TJZgsxpfOmltUUChMzlEM.md +++ b/roadmaps/software-design-architecture/content/clean-code@TJZgsxpfOmltUUChMzlEM.md @@ -1,17 +1,6 @@ # Clean Code Principles -Clean code is code that is easy to read, understand, and maintain. It follows a set of principles that are designed to make the code more readable, testable, and less error-prone. Some of the key principles of clean code include: - -* Clarity: The code should be easy to read and understand. -* Simplicity: The code should be as simple as possible, avoiding unnecessary complexity. -* Comments: Comments should be used sparingly and only when necessary to explain complex or non-obvious code. -* Naming: Variables, functions, and classes should have meaningful and descriptive names. -* Formatting: The code should be consistently formatted to improve readability. -* Functionality: The code should be organized into small, single-purpose functions and classes. -* Error handling: The code should handle errors in a consistent and predictable way. -* Testing: The code should be testable and have a high test coverage. -* Reusability: The code should be designed to be reusable and modular. -* Performance: The code should be designed to be efficient and performant. +Clean code refers to code that is easy to read, understand, and modify, following practices like meaningful naming, small functions, and clear structure. It prioritizes clarity over cleverness, since code is read far more often than it is written. Writing clean code reduces the time needed to fix bugs or add features, and it makes collaboration easier when multiple developers work on the same codebase. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/client-server@ZGIMUaNfBwE5b6O1yexSz.md b/roadmaps/software-design-architecture/content/client-server@ZGIMUaNfBwE5b6O1yexSz.md index 3c5cac669..f75a026ef 100644 --- a/roadmaps/software-design-architecture/content/client-server@ZGIMUaNfBwE5b6O1yexSz.md +++ b/roadmaps/software-design-architecture/content/client-server@ZGIMUaNfBwE5b6O1yexSz.md @@ -1,8 +1,6 @@ # Client Server -The client-server architecture is a common architecture pattern used in distributed systems, where a client (or multiple clients) send requests to a server, and the server responds to those requests. The client and server are separate entities that communicate over a network, such as the Internet or a local network. - -The client is responsible for presenting the user interface and handling user input, while the server is responsible for processing the requests and returning the appropriate response. The server can also handle tasks such as data storage, security, and business logic. +Client-server is a distributed architecture where clients request services or resources and servers provide them over a network. The client handles the user interface and user interaction, while the server manages data storage, business logic, and processing. This separation lets multiple clients share the same server resources and allows each side to be scaled or updated independently. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/commands--queries@j_SUD3SxpKYZstN9LSP82.md b/roadmaps/software-design-architecture/content/commands--queries@j_SUD3SxpKYZstN9LSP82.md index 393e10e40..a7e9394a4 100644 --- a/roadmaps/software-design-architecture/content/commands--queries@j_SUD3SxpKYZstN9LSP82.md +++ b/roadmaps/software-design-architecture/content/commands--queries@j_SUD3SxpKYZstN9LSP82.md @@ -1,8 +1,6 @@ # Commands Queries -The Command and Query Responsibility Segregation (CQRS) pattern is a technique used in enterprise application development to separate the responsibilities of handling command (write) operations and query (read) operations for performing actions that change the state of the system, such as creating, updating, or deleting data. These operations are handled by Command Handlers, which are responsible for validating the data and executing the appropriate business logic. - -Queries are used for retrieving data from the system, such as reading data from a database or a cache. These operations are handled by Query Handlers, which are responsible for executing the appropriate query and returning the data to the caller. +The Command and Query Responsibility Segregation (CQRS) pattern separates operations that change a system's state, called commands, from operations that read data, called queries. A command performs an action such as creating or updating a record and returns no data, while a query returns data without producing any side effects. Keeping these two categories distinct clarifies the intent of each operation and makes it easier to scale or cache reads independently of writes. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/component-based@a0geFJWl-vi3mYytTjYdb.md b/roadmaps/software-design-architecture/content/component-based@a0geFJWl-vi3mYytTjYdb.md index 7be2f789a..df889d5a0 100644 --- a/roadmaps/software-design-architecture/content/component-based@a0geFJWl-vi3mYytTjYdb.md +++ b/roadmaps/software-design-architecture/content/component-based@a0geFJWl-vi3mYytTjYdb.md @@ -1,8 +1,6 @@ # Component Based -In software architecture, component-based design (CBD) is an approach to designing software systems by composing them from a set of reusable and independent software components. These components encapsulate specific functionality and can be easily integrated into different parts of the system, allowing for a more modular and flexible design. - -In CBD, a software system is divided into a set of components, each of which has a well-defined interface and a specific responsibility. These components can be developed, tested, and deployed independently, making it easier to add new features, modify existing ones, and maintain the system. +Component-based architecture divides a system into independent, reusable components, each encapsulating a specific piece of functionality behind a well-defined interface. Components can be developed, tested, and replaced separately, as long as their interfaces stay stable. This approach supports reuse across different parts of an application or even across different projects. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/component-principles@8Bm0sRhUg6wZtnvtTmpgY.md b/roadmaps/software-design-architecture/content/component-principles@8Bm0sRhUg6wZtnvtTmpgY.md index 3c81da966..bf89a1ace 100644 --- a/roadmaps/software-design-architecture/content/component-principles@8Bm0sRhUg6wZtnvtTmpgY.md +++ b/roadmaps/software-design-architecture/content/component-principles@8Bm0sRhUg6wZtnvtTmpgY.md @@ -1,17 +1,6 @@ # Component Principles -Component principles in software architecture refer to guidelines for designing and implementing software components that are modular, reusable, and easy to understand, test, and maintain. Some of the key component principles in software architecture include: - -* High cohesion -* Low coupling -* Separation of concerns -* Interface-based design -* Reusability -* Testability -* Modularity -* Interoperability - -By following these component principles, software can be developed in a way that is easy to understand, maintain, and extend, and that is less prone to bugs. It also enables better code reuse, and makes it easier to test and change the code, and also enables better code reuse, as components can be reused in different contexts. +Component principles are a set of guidelines used to organize software into cohesive, reusable, and decoupled modules. These principles address how to group classes and modules together to balance the competing needs of maintainability, flexibility, and independent deployability. By focusing on how components interact and evolve, developers can minimize the impact of changes and ensure that systems remain stable as they grow in complexity. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/composition-over-inheritance@Izno7xX7wDvwPEg7f_d1Y.md b/roadmaps/software-design-architecture/content/composition-over-inheritance@Izno7xX7wDvwPEg7f_d1Y.md index c36cedb00..158349620 100644 --- a/roadmaps/software-design-architecture/content/composition-over-inheritance@Izno7xX7wDvwPEg7f_d1Y.md +++ b/roadmaps/software-design-architecture/content/composition-over-inheritance@Izno7xX7wDvwPEg7f_d1Y.md @@ -1,11 +1,9 @@ # Composition over Inheritance -Composition over inheritance is a programming principle that suggests that it is better to use composition, a mechanism for assembling objects, to create complex objects, rather than using inheritance, which is a mechanism for creating new classes based on existing ones. - -Inheritance is a powerful mechanism for creating reusable code, but it can also lead to tightly coupled, hard-to-maintain code. This is because inherited classes are tightly bound to their parent classes and any changes made to the parent class will affect all of its child classes. This makes it hard to change or extend the code without affecting the entire class hierarchy. +Composition over inheritance is a design principle that suggests achieving code reuse by assembling complex objects from simpler ones rather than inheriting behavior from a parent class. Instead of creating deep and rigid class hierarchies, this approach encourages developers to define small, focused components that can be combined or swapped out to build specific functionality. This method leads to more flexible and maintainable code because it reduces the tight coupling between classes and prevents the complications that arise from complex inheritance chains. Visit the following resources to learn more: - [@article@Overview of Composition over Inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance) - [@video@Tutorial - Composition over Inheritance](https://www.youtube.com/watch?v=wfMtDGfHWpA) -- [@video@Composition over Inheritance Explained by Games](https://www.youtube.com/watch?v=HNzP1aLAffM&list=PLCl5BUbK0jXt5l18S5UNAoUc4eQ2PJDye) +- [@video@Composition over Inheritance Explained by Games](https://www.youtube.com/watch?v=HNzP1aLAffM&list=PLCl5BUbK0jXt5l18S5UNAoUc4eQ2PJDye) \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/concrete-classes@hd6GJ-H4p9I4aaiRTni57.md b/roadmaps/software-design-architecture/content/concrete-classes@hd6GJ-H4p9I4aaiRTni57.md index f9dfd8993..4e93b2239 100644 --- a/roadmaps/software-design-architecture/content/concrete-classes@hd6GJ-H4p9I4aaiRTni57.md +++ b/roadmaps/software-design-architecture/content/concrete-classes@hd6GJ-H4p9I4aaiRTni57.md @@ -1,5 +1,3 @@ # Concrete Classes -A concrete class is a class in object-oriented programming (OOP) that can be instantiated, meaning objects can be created from it. A concrete class is a class that provides an implementation for all of the abstract methods declared in its parent class, if it inherits from an abstract class. A concrete class can also be a class that does not inherit from an abstract class, in that case it can have implementation for all of its methods. - -Concrete classes are used to provide specific implementation details for a group of related classes that inherit from a common abstract class. They are also used to define unique behavior for a specific class. A concrete class can have its own methods and variables, and can also override the methods of its parent class. \ No newline at end of file +A concrete class is a blueprint in object-oriented programming that provides a complete implementation for all of its defined methods and properties. It serves as a tangible template that allows developers to create direct instances, or objects, which can then be utilized to perform tasks within an application. Unlike abstract classes or interfaces, a concrete class does not contain incomplete methods, ensuring that every defined behavior is fully operational and ready for immediate execution upon instantiation. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/coupling-and-cohesion@TXus3R5vVQDBeBag6B5qs.md b/roadmaps/software-design-architecture/content/coupling-and-cohesion@TXus3R5vVQDBeBag6B5qs.md index 862821392..daae71b67 100644 --- a/roadmaps/software-design-architecture/content/coupling-and-cohesion@TXus3R5vVQDBeBag6B5qs.md +++ b/roadmaps/software-design-architecture/content/coupling-and-cohesion@TXus3R5vVQDBeBag6B5qs.md @@ -1,10 +1,6 @@ # Coupling and Cohesion -Coupling and cohesion are two principles in software architecture that are used to measure the degree of interdependence between components in a system. - -Coupling refers to the degree to which one component depends on another component. High coupling means that a change in one component will likely affect other components, making the system more difficult to understand, test, and maintain. Low coupling, on the other hand, means that changes to one component have minimal impact on other components, making the system more modular and easier to understand, test, and maintain. - -Cohesion, on the other hand, refers to the degree to which the responsibilities of a component are related to each other. High cohesion means that a component has a single, well-defined purpose and that all its functionality and data is related to that purpose. Low cohesion, on the other hand, means that a component has multiple, unrelated responsibilities, making it more difficult to understand, test, and maintain. +Coupling measures how much one module depends on another, while cohesion measures how closely the responsibilities within a single module relate to each other. Low coupling and high cohesion make a codebase easier to change, since a module can be modified or replaced without breaking unrelated parts of the system. Tightly coupled modules tend to cause cascading changes across a codebase, while low cohesion spreads unrelated logic across a single module, making it harder to understand and test. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/cqrs@IU86cGkLPMXUJKvTBywPu.md b/roadmaps/software-design-architecture/content/cqrs@IU86cGkLPMXUJKvTBywPu.md index c9c92f8da..717a9aefc 100644 --- a/roadmaps/software-design-architecture/content/cqrs@IU86cGkLPMXUJKvTBywPu.md +++ b/roadmaps/software-design-architecture/content/cqrs@IU86cGkLPMXUJKvTBywPu.md @@ -1,8 +1,6 @@ # CQRS -CQRS (Command Query Responsibility Segregation) is an architectural pattern that is used to separate the responsibilities of reading and writing data in a software system. In a CQRS architecture, the system is divided into two separate parts: the command side and the query side. - -The command side is responsible for processing commands and updating the system's state, while the query side is responsible for reading the current state of the system and returning the results to the client. The command and query sides can use different data models, storage mechanisms, and even different technologies. +Command Query Responsibility Segregation, or CQRS, separates the operations that change data, called commands, from the operations that read data, called queries, often using different models for each. This separation allows the read and write sides of a system to be optimized, scaled, and even stored independently. CQRS is often paired with event sourcing, since events naturally represent the commands that changed the system's state. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/design-patterns@Jd79KXxZavpnp3mtE1q0n.md b/roadmaps/software-design-architecture/content/design-patterns@Jd79KXxZavpnp3mtE1q0n.md index 49c1d986a..d3342e52e 100644 --- a/roadmaps/software-design-architecture/content/design-patterns@Jd79KXxZavpnp3mtE1q0n.md +++ b/roadmaps/software-design-architecture/content/design-patterns@Jd79KXxZavpnp3mtE1q0n.md @@ -1,13 +1,6 @@ # Design Patterns -Design patterns are general solutions to common problems that arise in software development. They provide a way to describe and communicate proven solutions to common design problems and they provide a common vocabulary for design. They are not specific to any particular programming language or technology, but rather describe the problem and the solution in a way that can be applied to many different contexts. - -There are several different types of design patterns, including: - -* Creational patterns -* Structural patterns -* Behavioral patterns -* Architectural patterns +Design patterns are reusable solutions to commonly occurring problems in software design. They represent best practices evolved over time by experienced software developers to address recurring challenges in structuring code. By providing a standardized vocabulary and template for solving structural or behavioral issues, these patterns help developers create systems that are more flexible, maintainable, and easier to understand. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/design-patterns@gyQw885dvupmkohzJPg3a.md b/roadmaps/software-design-architecture/content/design-patterns@gyQw885dvupmkohzJPg3a.md index 49c1d986a..d0e6ed5c7 100644 --- a/roadmaps/software-design-architecture/content/design-patterns@gyQw885dvupmkohzJPg3a.md +++ b/roadmaps/software-design-architecture/content/design-patterns@gyQw885dvupmkohzJPg3a.md @@ -1,13 +1,6 @@ # Design Patterns -Design patterns are general solutions to common problems that arise in software development. They provide a way to describe and communicate proven solutions to common design problems and they provide a common vocabulary for design. They are not specific to any particular programming language or technology, but rather describe the problem and the solution in a way that can be applied to many different contexts. - -There are several different types of design patterns, including: - -* Creational patterns -* Structural patterns -* Behavioral patterns -* Architectural patterns +Design patterns are general, reusable solutions to common problems that occur when designing software at the level of individual classes and objects. They describe proven approaches to structuring relationships between objects, such as how to create objects flexibly or how to let objects react to changes in other objects. The Gang of Four catalog, which includes patterns like Singleton, Factory, and Observer, is one of the most widely referenced sources for these patterns. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/design-principles@9dMbo4Q1_Sd9wW6-HSCA9.md b/roadmaps/software-design-architecture/content/design-principles@9dMbo4Q1_Sd9wW6-HSCA9.md index 7ed4d42ad..de751982d 100644 --- a/roadmaps/software-design-architecture/content/design-principles@9dMbo4Q1_Sd9wW6-HSCA9.md +++ b/roadmaps/software-design-architecture/content/design-principles@9dMbo4Q1_Sd9wW6-HSCA9.md @@ -1,3 +1,3 @@ # Design Principles -Design principles are guidelines for writing clean, maintainable code — with SOLID, DRY, YAGNI, and composition over inheritance among the most well-known. Applied at the module and class level, they reduce coupling, improve readability, and make the codebase easier to extend and test. +Design principles are guidelines for writing clean, maintainable code — with SOLID, DRY, YAGNI, and composition over inheritance among the most well-known. Applied at the module and class level, they reduce coupling, improve readability, and make the codebase easier to extend and test. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/distributed@3V74lLPlcOXFB-QRTUA5j.md b/roadmaps/software-design-architecture/content/distributed@3V74lLPlcOXFB-QRTUA5j.md index b159c20fd..47a3583fc 100644 --- a/roadmaps/software-design-architecture/content/distributed@3V74lLPlcOXFB-QRTUA5j.md +++ b/roadmaps/software-design-architecture/content/distributed@3V74lLPlcOXFB-QRTUA5j.md @@ -1,6 +1,6 @@ # Distributed -Distributed systems refer to the design and organization of software components that are distributed across multiple devices or locations, connected via a network, and work together to achieve a common goal. The main challenge in designing distributed systems is dealing with the inherent complexity that arises from the distribution of components and the communication between them, and it requires techniques such as load balancing, replication, and partitioning to improve scalability, fault-tolerance, and performance. Additionally, security and coordination are also important aspects of distributed systems. +A distributed architecture spreads a system's components across multiple machines or networks that communicate to work as a single system. This approach improves scalability and fault tolerance, since the failure of one machine does not necessarily bring down the whole system. It also introduces challenges around network latency, data consistency, and coordination between nodes that a single-machine system does not face. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/domain-driven-design@CD20zA6k9FxUpMgHnNYRJ.md b/roadmaps/software-design-architecture/content/domain-driven-design@CD20zA6k9FxUpMgHnNYRJ.md index 6f71d0874..eb7ce16dc 100644 --- a/roadmaps/software-design-architecture/content/domain-driven-design@CD20zA6k9FxUpMgHnNYRJ.md +++ b/roadmaps/software-design-architecture/content/domain-driven-design@CD20zA6k9FxUpMgHnNYRJ.md @@ -1,6 +1,6 @@ # Domain Driven Design -Domain-Driven Design (DDD) is an architectural pattern that is used to design software systems based on the core business domain and business entities, it's focused on creating a clear and accurate representation of the business domain within the software system, and on aligning the software system with the business goals and objectives. DDD provides several advantages over other architectural patterns, such as alignment with business goals and objectives, improved communication between domain experts and developers, a clear and expressive model of the business domain and improved scalability and maintainability. It's implemented using a set of principles and patterns such as strategic design, subdomains, bounded context, entities, value objects, aggregate, and repository. +Domain-Driven Design is an approach to software design that models the software's structure and language around the business domain it serves. It encourages close collaboration between developers and domain experts to build a shared vocabulary, called a ubiquitous language, that is reflected directly in the code. Concepts like entities, value objects, and bounded contexts come from this approach and help keep complex business logic organized. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/domain-language@kWNQd3paQrhMHMJzM35w8.md b/roadmaps/software-design-architecture/content/domain-language@kWNQd3paQrhMHMJzM35w8.md index 7cecaadeb..5f74841a5 100644 --- a/roadmaps/software-design-architecture/content/domain-language@kWNQd3paQrhMHMJzM35w8.md +++ b/roadmaps/software-design-architecture/content/domain-language@kWNQd3paQrhMHMJzM35w8.md @@ -1,8 +1,6 @@ # Domain Language -A domain language is a specific vocabulary and set of concepts used to describe and communicate about a specific area of knowledge or business. In software development, a domain language is used to model the objects and concepts within a specific domain, and to capture the relationships and constraints between them. - -A domain language is used to provide a common understanding of the problem domain among all stakeholders, including developers, business analysts, and domain experts. It is also used to ensure that the software system accurately reflects the real-world problem it is intended to solve. +Domain language refers to a specialized vocabulary and set of terms used by developers and domain experts to describe the specific concepts, processes, and rules of a business area. By establishing a shared vocabulary, it bridges the gap between technical implementation and business requirements, ensuring that the software design directly reflects the reality of the problem space. This approach relies on maintaining a consistent mapping between the code structure and the terminology used by stakeholders, which helps in creating a more intuitive and maintainable system. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/domain-models@I25ghe8xYWpZ-9pRcHfOh.md b/roadmaps/software-design-architecture/content/domain-models@I25ghe8xYWpZ-9pRcHfOh.md index d7be7381e..e73424925 100644 --- a/roadmaps/software-design-architecture/content/domain-models@I25ghe8xYWpZ-9pRcHfOh.md +++ b/roadmaps/software-design-architecture/content/domain-models@I25ghe8xYWpZ-9pRcHfOh.md @@ -1,8 +1,6 @@ # Domain Models -A domain model is a representation of a specific area of knowledge or business that is used to model the objects and concepts within that domain, and to capture the relationships and constraints between them. In object-oriented programming (OOP), a domain model is typically represented by a set of classes and interfaces, with each class or interface representing a specific concept or object within the domain. - -A domain model is used to provide a clear and consistent representation of the problem domain, and to capture the business requirements and constraints of the system. It is also used to guide the design of the system and to ensure that the system accurately reflects the real-world problem it is intended to solve. +A domain model is a conceptual representation of the real-world objects, entities, and processes that exist within a specific area of business or subject matter. It acts as a bridge between technical implementation and business requirements by documenting the relationships, attributes, and behaviors of core elements. Developers use these models to establish a common vocabulary and structure that ensures the software effectively reflects the logic of the problem it intends to solve. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/domain-models@NpSfbzYtGebmfrifkKsUf.md b/roadmaps/software-design-architecture/content/domain-models@NpSfbzYtGebmfrifkKsUf.md index fe4eb11df..ef13e8e4d 100644 --- a/roadmaps/software-design-architecture/content/domain-models@NpSfbzYtGebmfrifkKsUf.md +++ b/roadmaps/software-design-architecture/content/domain-models@NpSfbzYtGebmfrifkKsUf.md @@ -1,8 +1,6 @@ # Domain Models -Domain Models are a pattern used in enterprise application development to represent the business concepts and rules of a specific domain. They are typically used to model the problem domain, or the area of expertise of a specific business. - -A Domain Model is a collection of objects that represent the real-world concepts and entities of the domain. These objects are typically modeled as classes or types, and they encapsulate the data and behavior that is specific to the domain. They are responsible for representing the state and behavior of the business concepts they model, and for enforcing the rules and constraints of the domain. +A domain model represents the concepts, rules, and relationships of a business domain within the software, combining data and behavior into objects like entities and value objects. It captures business logic directly in these objects rather than spreading it across separate procedural scripts. A rich domain model makes it easier to express complex business rules clearly and keep them consistent as the application grows. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/dry@ltBnVWZ3UMAuUvDkU6o4P.md b/roadmaps/software-design-architecture/content/dry@ltBnVWZ3UMAuUvDkU6o4P.md index 053946529..cf7752edb 100644 --- a/roadmaps/software-design-architecture/content/dry@ltBnVWZ3UMAuUvDkU6o4P.md +++ b/roadmaps/software-design-architecture/content/dry@ltBnVWZ3UMAuUvDkU6o4P.md @@ -1,8 +1,6 @@ -# DRY +# DRY (Don't Repeat Yourself) -DRY (Don't Repeat Yourself) is a software development principle that suggests that code should not have duplicate functionality. The idea is to keep the codebase as simple as possible by eliminating redundancy and duplication. The goal is to reduce complexity and improve maintainability by ensuring that each piece of knowledge is expressed in a single, unambiguous way within the system. - -The DRY principle is closely related to the Single Responsibility Principle (SRP) and the Open-Closed Principle (OCP), which are part of the SOLID principles. The DRY principle aims to reduce the amount of duplicate code by creating abstractions that can be reused across the system. +DRY is a software development principle aimed at reducing the repetition of information and logic within a system. It suggests that every piece of knowledge or functionality should have a single, unambiguous representation within an application. By centralizing logic and avoiding redundant code, developers make systems easier to maintain, test, and update, as any necessary changes only need to be applied in one location. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/encapsulate-what-varies@DlefJ9JuJ1LdQYC4WSx6y.md b/roadmaps/software-design-architecture/content/encapsulate-what-varies@DlefJ9JuJ1LdQYC4WSx6y.md index 2962446ff..3844adc4f 100644 --- a/roadmaps/software-design-architecture/content/encapsulate-what-varies@DlefJ9JuJ1LdQYC4WSx6y.md +++ b/roadmaps/software-design-architecture/content/encapsulate-what-varies@DlefJ9JuJ1LdQYC4WSx6y.md @@ -1,8 +1,6 @@ -# Encapsulate What Varies +# Encapsulate what varies -Encapsulate what varies is a programming principle that suggests that code should be organized in such a way that the parts that are likely to change in the future are isolated from the parts that are unlikely to change. This is accomplished by creating interfaces and classes that separate the varying parts of the code from the stable parts. - -Encapsulating what varies allows for more flexibility in the code. When changes are needed, they can be made to the encapsulated parts without affecting the rest of the code. This makes it easier to understand, test, and maintain the code. +Encapsulate what varies is a fundamental design principle that suggests identifying the parts of an application that are likely to change and separating them from the parts that remain constant. By isolating volatile code behind stable interfaces or abstractions, developers can modify or extend functionality without disrupting the rest of the system. This practice reduces the impact of future changes and makes the codebase easier to maintain, as updates are confined to specific, well-defined modules rather than spread across the entire architecture. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/encapsulation@GJxfVjhiLuuc36hatx9dP.md b/roadmaps/software-design-architecture/content/encapsulation@GJxfVjhiLuuc36hatx9dP.md index 637beaa56..3a9b45baf 100644 --- a/roadmaps/software-design-architecture/content/encapsulation@GJxfVjhiLuuc36hatx9dP.md +++ b/roadmaps/software-design-architecture/content/encapsulation@GJxfVjhiLuuc36hatx9dP.md @@ -1,8 +1,6 @@ # Encapsulation -Encapsulation is a concept in object-oriented programming (OOP) that refers to the practice of wrapping an object's internal data and behavior within a defined interface, and hiding the implementation details from the outside world. It is one of the fundamental concepts of OOP and is closely related to the concepts of data hiding and information hiding. - -Encapsulation is achieved by using access modifiers (such as "public," "private," and "protected") to control the visibility and accessibility of an object's data and methods. For example, data members of a class can be declared as private, which means they can only be accessed by methods within the class, while methods can be declared as public, which means they can be called by any code that has a reference to the object. +Encapsulation is a fundamental principle of object-oriented programming that bundles data and the methods that operate on that data into a single unit, known as a class. It restricts direct access to an object's internal state by hiding its private implementation details from the outside world. Developers expose only the necessary functionality through a public interface, which helps prevent accidental corruption of data and ensures that the internal logic of an object remains consistent and protected. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/enterprise-patterns@h0aeBhQRkDxNeFwDxT4Tf.md b/roadmaps/software-design-architecture/content/enterprise-patterns@h0aeBhQRkDxNeFwDxT4Tf.md index 712d13aec..7e191544f 100644 --- a/roadmaps/software-design-architecture/content/enterprise-patterns@h0aeBhQRkDxNeFwDxT4Tf.md +++ b/roadmaps/software-design-architecture/content/enterprise-patterns@h0aeBhQRkDxNeFwDxT4Tf.md @@ -1,16 +1,6 @@ # Enterprise Patterns -Enterprise patterns are a set of design patterns that are commonly used in the development of enterprise software applications. These patterns provide a common vocabulary and a set of best practices for solving common problems that arise in the development of large, complex software systems. Some examples of enterprise patterns include: - -* Domain-Driven Design (DDD) -* Model-View-Controller (MVC) -* Service Oriented Architecture (SOA) -* Command and Query Responsibility Segregation (CQRS) -* Event Sourcing -* Microservices -* Event-Driven Architecture (EDA) - -These patterns can help to improve the maintainability and scalability of the software, by providing a clear separation of concerns and allowing for a more modular and flexible architecture. +Enterprise patterns are reusable solutions to common problems found in business applications, particularly around organizing business logic and managing data access. They cover concerns such as how to represent business objects, how to move data between layers, and how to structure database access. Martin Fowler's book on enterprise application architecture documents many of these patterns, including data transfer objects, repositories, and the active record pattern. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/entities@VnW_7dl5G0IFL9W3YF_W3.md b/roadmaps/software-design-architecture/content/entities@VnW_7dl5G0IFL9W3YF_W3.md index 0689dba2c..e9efe3ea6 100644 --- a/roadmaps/software-design-architecture/content/entities@VnW_7dl5G0IFL9W3YF_W3.md +++ b/roadmaps/software-design-architecture/content/entities@VnW_7dl5G0IFL9W3YF_W3.md @@ -1,5 +1,3 @@ # Entities -Entities are a pattern used in enterprise application development to represent the business concepts that have a unique identity and a lifetime. They are typically used to model real-world objects or concepts that have a distinct identity and a lifecycle, such as a customer, an order, or an account. - -An Entity is defined by its identity, meaning that two entities with the same identity are considered to be the same, regardless of their state. Entities usually have a unique identifier, such as a primary key, that is used to identify them. They also have an associated set of properties or attributes that describe their state. \ No newline at end of file +An entity is an object defined by a unique identity that persists over time, even as its attributes change. Two entities with identical attributes are still considered different if they have different identities, unlike value objects. Entities typically represent core business concepts, such as a customer or an order, and carry the identity needed to track and reference them throughout the system's lifecycle. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/event-driven@KtzcJBb6-EcIoXnwYvE7a.md b/roadmaps/software-design-architecture/content/event-driven@KtzcJBb6-EcIoXnwYvE7a.md index b79309294..995d115cf 100644 --- a/roadmaps/software-design-architecture/content/event-driven@KtzcJBb6-EcIoXnwYvE7a.md +++ b/roadmaps/software-design-architecture/content/event-driven@KtzcJBb6-EcIoXnwYvE7a.md @@ -1,8 +1,6 @@ # Event Driven -Event-driven architecture (EDA) is a software design pattern in which the system reacts to specific events that occur, rather than being continuously polled for changes. In EDA, events are messages that are sent asynchronously between components, and the components react to the events they are interested in. - -The main advantage of using EDA is that it allows for a clear separation of concerns between the components, and it can improve the scalability and fault-tolerance of the system. Additionally, it allows for loose coupling between components, meaning that the components are not aware of each other's existence, and can be developed, deployed, and scaled independently. +Event-driven architecture structures a system around the production, detection, and consumption of events, which are records of something that happened. Components react to events asynchronously instead of calling each other directly, which reduces coupling between producers and consumers. This style suits systems that need to scale independently or respond quickly to changes, such as order processing or real-time notifications. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/event-sourcing@K8X_-bsiy7gboInPzbiEb.md b/roadmaps/software-design-architecture/content/event-sourcing@K8X_-bsiy7gboInPzbiEb.md index 46bf7cbe5..d608ebfa3 100644 --- a/roadmaps/software-design-architecture/content/event-sourcing@K8X_-bsiy7gboInPzbiEb.md +++ b/roadmaps/software-design-architecture/content/event-sourcing@K8X_-bsiy7gboInPzbiEb.md @@ -1,12 +1,10 @@ # Event Sourcing -Event sourcing is an architectural pattern that is used to build systems that need to maintain a history of all the changes that have occurred over time. This pattern stores all changes to the system's state as a sequence of events, rather than just the current state. - -In Event sourcing, all changes to the state of the system are treated as events, and these events are stored in an append-only log, also known as an event store. The current state of the system can be reconstructed from the event log at any given point in time by replaying the events from the log. +Event sourcing stores the state of an application as a sequence of events rather than storing only the current state. Each change to the system is captured as an immutable event, and the current state is derived by replaying those events in order. This approach provides a complete audit trail of every change and makes it possible to reconstruct past states, though it requires careful handling of event versioning and storage growth over time. Visit the following resources to learn more: - [@article@Event Sourcing Pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/event-sourcing) - [@video@Event Sourcing Example & Explained](https://www.youtube.com/watch?v=AUj4M-st3ic&list=PLThyvG1mlMzkRKJnhzvxtSAbY8oxENLUQ&ab_channel=CodeOpinion) -- [@feed@Explore top posts about Architecture](https://app.daily.dev/tags/architecture?ref=roadmapsh) - [@video@Event Sourcing Explained Using Football](https://www.youtube.com/watch?v=xPmQxYIi5fA&list=PLCl5BUbK0jXt5l18S5UNAoUc4eQ2PJDye) +- [@feed@Explore top posts about Architecture](https://app.daily.dev/tags/architecture?ref=roadmapsh) \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/gof-design-patterns@hlHl00ELlK9YdnzHDGnEW.md b/roadmaps/software-design-architecture/content/gof-design-patterns@hlHl00ELlK9YdnzHDGnEW.md index a2f3eae58..d1b26664e 100644 --- a/roadmaps/software-design-architecture/content/gof-design-patterns@hlHl00ELlK9YdnzHDGnEW.md +++ b/roadmaps/software-design-architecture/content/gof-design-patterns@hlHl00ELlK9YdnzHDGnEW.md @@ -1,12 +1,6 @@ # GoF Design Patterns -The Gang of Four (GoF) design patterns are a set of design patterns for object-oriented software development that were first described in the book "Design Patterns: Elements of Reusable Object-Oriented Software" by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (also known as the Gang of Four). - -The GoF design patterns are divided into three categories: Creational, Structural and Behavioral. - -* Creational Patterns -* Structural Patterns -* Behavioral Patterns +GoF Design Patterns are a set of reusable solutions to common problems encountered during software design. Originally documented by the "Gang of Four" (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides), these patterns provide standardized approaches for structuring classes and objects to create flexible and maintainable systems. They are categorized into three main types: creational patterns, which handle object creation mechanisms; structural patterns, which simplify relationships between entities; and behavioral patterns, which focus on communication between objects. Using these patterns helps developers apply proven architectural concepts to solve complex programming challenges effectively. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/hollywood-principle@WzUhKlmFB9alTlAyV-MWJ.md b/roadmaps/software-design-architecture/content/hollywood-principle@WzUhKlmFB9alTlAyV-MWJ.md index f5fd7d8eb..7593a9342 100644 --- a/roadmaps/software-design-architecture/content/hollywood-principle@WzUhKlmFB9alTlAyV-MWJ.md +++ b/roadmaps/software-design-architecture/content/hollywood-principle@WzUhKlmFB9alTlAyV-MWJ.md @@ -1,8 +1,6 @@ # Hollywood Principle -The Hollywood Principle is a software development principle that states: "Don't call us, we'll call you." It suggests that high-level components should dictate the flow of control in an application, rather than low-level components. - -This principle is often used in the context of inversion of control (IoC) and dependency injection. In traditional software development, low-level components are responsible for creating and managing the high-level components that they depend on. With IoC, the high-level components dictate the flow of control, and the low-level components are created and managed by a separate mechanism. +The Hollywood Principle is a design strategy that dictates that high-level components should control the flow of an application while low-level components are only called upon when needed. Instead of low-level modules actively polling or calling higher-level functions, the system informs the lower-level parts of the application when it is their turn to execute. This approach minimizes dependencies and prevents tight coupling, as lower-level modules do not need to know about the internal logic or the existence of the components that invoke them. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/identity-maps@tb0X1HtuiGwz7YhQ5xPsV.md b/roadmaps/software-design-architecture/content/identity-maps@tb0X1HtuiGwz7YhQ5xPsV.md index 37c50335a..b5f83c6c1 100644 --- a/roadmaps/software-design-architecture/content/identity-maps@tb0X1HtuiGwz7YhQ5xPsV.md +++ b/roadmaps/software-design-architecture/content/identity-maps@tb0X1HtuiGwz7YhQ5xPsV.md @@ -1,8 +1,6 @@ # Identity Maps -Identity Maps is a pattern used in enterprise application development to maintain a map of objects that have been loaded from the database, keyed by their unique identifier. It is used to ensure that multiple copies of the same object are not created in memory when the same data is accessed multiple times. - -The identity map pattern is typically used in conjunction with an ORM (Object-Relational Mapping) tool. When an object is loaded from the database, it is first checked against the identity map to see if it has already been loaded. If it has, the existing object is returned, instead of creating a new copy. +An identity map is a pattern that keeps track of every object loaded from a database during a single unit of work, mapping each object to its unique identifier. When the same object is requested again, the identity map returns the existing instance instead of loading a new copy from the database. This avoids duplicate objects representing the same underlying data and helps maintain consistency when multiple parts of the code work with the same record. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/indentation-and-code-style@81WOL1nxb56ZbAOvxJ7NK.md b/roadmaps/software-design-architecture/content/indentation-and-code-style@81WOL1nxb56ZbAOvxJ7NK.md index 536c6983a..b5d1dd2e0 100644 --- a/roadmaps/software-design-architecture/content/indentation-and-code-style@81WOL1nxb56ZbAOvxJ7NK.md +++ b/roadmaps/software-design-architecture/content/indentation-and-code-style@81WOL1nxb56ZbAOvxJ7NK.md @@ -1,6 +1,6 @@ # Indentation and Code Style -Indentation and code style refer to the consistent formatting of source code to improve readability and maintainability. This involves using whitespace, line breaks, and naming conventions in a standardized manner across a project. The goal is to create code that is visually appealing and easy for developers to understand, regardless of who wrote it. Consistent indentation highlights the code's structure, making it easier to follow control flow and identify logical blocks. Adhering to a specific code style, which dictates rules for naming, commenting, and other formatting aspects, further enhances the clarity and consistency of the codebase. +Indentation and code style refer to the visual layout and formatting rules applied to source code to improve its readability and consistency. This involves standardizing the use of spaces or tabs for nesting, defining line lengths, and following naming conventions for variables and functions. By maintaining a uniform appearance across a codebase, developers can easily scan and understand the structure of the logic without being distracted by irregular spacing or inconsistent syntax patterns. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/interfaces@SrcPhS4F7aT80qNjbv54f.md b/roadmaps/software-design-architecture/content/interfaces@SrcPhS4F7aT80qNjbv54f.md index 6c37d617d..3c68cb5bb 100644 --- a/roadmaps/software-design-architecture/content/interfaces@SrcPhS4F7aT80qNjbv54f.md +++ b/roadmaps/software-design-architecture/content/interfaces@SrcPhS4F7aT80qNjbv54f.md @@ -1,8 +1,6 @@ # Interfaces -In object-oriented programming (OOP), an interface is a contract or a set of methods that a class must implement. It defines a common set of methods that a class must provide, but it does not provide any implementation details. An interface can include both method signatures and constants. - -Interfaces are used to define a common behavior for a group of related classes, and to provide a way for objects of different classes to be treated polymorphically. A class that implements an interface must provide an implementation for all of the methods declared in the interface. A class can implement multiple interfaces, but can only inherit from one base class. +An interface is a programming contract that defines a set of methods or properties that a class must implement without specifying how those members should function. It serves as a blueprint for classes, allowing developers to ensure that different objects adhere to a common structure regardless of their internal implementation. By decoupling the definition of behavior from the actual code, interfaces promote flexibility and allow for polymorphism, where different objects can be treated interchangeably as long as they satisfy the same interface requirements. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/keep-framework-code-distant@OoCCy-3W5y7bUcKz_iyBw.md b/roadmaps/software-design-architecture/content/keep-framework-code-distant@OoCCy-3W5y7bUcKz_iyBw.md index 707176ff0..f2a16c65a 100644 --- a/roadmaps/software-design-architecture/content/keep-framework-code-distant@OoCCy-3W5y7bUcKz_iyBw.md +++ b/roadmaps/software-design-architecture/content/keep-framework-code-distant@OoCCy-3W5y7bUcKz_iyBw.md @@ -1,16 +1,6 @@ -# Keep Framework Code Distant +# Keep framework code distant -Keeping framework code distant refers to separating the application's code from the framework's code. By doing so, it makes it easier to maintain, test, and upgrade the application's codebase and the framework independently. - -Here are some ways to keep framework code distant in system architecture: - -1. Use an abstraction layer to separate the application code from the framework code. This allows the application code to be written without the need to know the specifics of the framework. -2. Use dependency injection to decouple the application code from the framework code. This allows the application code to use the framework's functionality without having to instantiate the framework objects directly. -3. Avoid using framework-specific libraries or classes in the application code. This makes it easier to switch to a different framework in the future if needed. -4. Use a standard interface for the application code to interact with the framework. This allows the application code to be written without the need to know the specifics of the framework. -5. Keep the application and the framework code in separate projects and/or repositories. - -By following these best practices, the system architecture will be more maintainable, testable, and less error-prone, and it will be easier to upgrade or switch the framework if needed. +Keeping framework code distant is a design practice that aims to decouple core business logic from the specific libraries or frameworks being used. It involves wrapping third-party tools within abstraction layers, such as interfaces or adapter classes, so that the application remains agnostic of the framework’s internal implementation. This approach ensures that if a framework needs to be updated, replaced, or removed, the impact on the codebase is minimized because the business rules are not directly tied to external dependencies. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/keep-it-simple-and-refactor-often@9naCfoHF1LW1OEsVZGi8v.md b/roadmaps/software-design-architecture/content/keep-it-simple-and-refactor-often@9naCfoHF1LW1OEsVZGi8v.md index d0acfe4f1..9b4dd1e13 100644 --- a/roadmaps/software-design-architecture/content/keep-it-simple-and-refactor-often@9naCfoHF1LW1OEsVZGi8v.md +++ b/roadmaps/software-design-architecture/content/keep-it-simple-and-refactor-often@9naCfoHF1LW1OEsVZGi8v.md @@ -1,16 +1,6 @@ -# Avoid Hasty Abstractions +# Keep it simple and refactor often -Creating abstractions is an important part of software development, but creating too many abstractions or creating them too early can lead to unnecessary complexity and make the code harder to understand and maintain. - -Here are some ways to avoid hasty abstractions in system architecture: - -* Understand the problem that needs to be solved before creating an abstraction. -* Start with a simple solution and only create an abstraction when it becomes clear that the solution is becoming too complex. -* Use code refactoring techniques to simplify the code before creating an abstraction. -* Avoid creating abstractions for the sake of creating abstractions. -* Use established design patterns and practices when creating abstractions, but do not force them into the code. -* Use automated testing to ensure that the abstraction does not introduce new bugs or break existing functionality. -* Create abstraction in a way that it's easy to test, debug, and reason about. +"Keep it simple and refactor often" is a development philosophy that encourages writing straightforward, readable code and frequently improving its internal structure without changing its external behavior. This approach focuses on reducing complexity by removing redundant logic and breaking down large tasks into manageable pieces. Developers maintain high code quality by addressing technical debt incrementally, ensuring that the software remains easy to understand, test, and adapt to future requirements as it evolves. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/law-of-demeter@vnLhItObDgp_XaDmplBsJ.md b/roadmaps/software-design-architecture/content/law-of-demeter@vnLhItObDgp_XaDmplBsJ.md index 810475906..914fe147e 100644 --- a/roadmaps/software-design-architecture/content/law-of-demeter@vnLhItObDgp_XaDmplBsJ.md +++ b/roadmaps/software-design-architecture/content/law-of-demeter@vnLhItObDgp_XaDmplBsJ.md @@ -1,34 +1,6 @@ # Law of Demeter -Also called “Principle of Least Knowledge”, it states: - -In Practice ------------ - -* Avoid chaining calls deep into the internals of other objects. -* Restrict communication to objects you directly manage. - -### 🔹 ❌ Bad Example (Violation) - - // Controller - total = order.customer.address.getRegionTaxRate() * order.amount - - -### 🔹 ✅ Good Example - - // Controller - total = order.calculateTotal() - - -🔹 Why It Matters ------------------ - -* **Reduces coupling** → fewer dependencies between classes. -* **Increases maintainability** → changes in one class don’t affect distant classes. -* **Improves readability** → clear boundaries of responsibility. - -🔹 Resources ------------- +The Law of Demeter is a design principle that restricts how objects interact with one another to reduce system coupling. It suggests that a given method should only call methods belonging to its own class, objects created within the method, objects passed as arguments, or direct component objects. By limiting these interactions to "only talk to your immediate friends," the principle ensures that a module does not need to know the internal structure or the navigation path of the objects it interacts with. This approach makes code easier to maintain and refactor because changes to the internal implementation of one object do not propagate across the entire system. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/layered-architectures@HN160YgryBBtVGjnWxNie.md b/roadmaps/software-design-architecture/content/layered-architectures@HN160YgryBBtVGjnWxNie.md index e741aeb0b..587373a4a 100644 --- a/roadmaps/software-design-architecture/content/layered-architectures@HN160YgryBBtVGjnWxNie.md +++ b/roadmaps/software-design-architecture/content/layered-architectures@HN160YgryBBtVGjnWxNie.md @@ -1,12 +1,6 @@ # Layered Architectures -A layered architecture is a software design pattern in which the functionality of a system is divided into a set of layers, with each layer having a specific responsibility and interacting with the layers above and below it. The main idea behind a layered architecture is to separate the concerns of the system into distinct and independent layers, making the code more modular, easier to understand, test, and modify. - -There are several types of layered architectures, but a common one is the three-layer architecture which consists of: - -* Presentation Layer -* Business Layer -* Data Access Layer +Layered architecture is a design pattern that organizes a software system into distinct horizontal segments or tiers, each with a specific responsibility. In this approach, components are grouped based on their function, such as presentation, business logic, or data access, with each layer communicating only with the one directly below it. By restricting dependencies in this manner, developers create a modular structure that makes it easier to update, test, and maintain individual parts of an application without affecting the entire codebase. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/layered@IELEJcKYdZ6VN-UIq-Wln.md b/roadmaps/software-design-architecture/content/layered@IELEJcKYdZ6VN-UIq-Wln.md index b4b9c766f..34ea6676b 100644 --- a/roadmaps/software-design-architecture/content/layered@IELEJcKYdZ6VN-UIq-Wln.md +++ b/roadmaps/software-design-architecture/content/layered@IELEJcKYdZ6VN-UIq-Wln.md @@ -1,8 +1,6 @@ # Layered -In software architecture, layered architecture is a design approach in which a software system is divided into a set of layers, each of which has a specific responsibility and communicates with the other layers through well-defined interfaces. This approach allows for a more modular and flexible design, where each layer can be developed, tested, and deployed independently, making it easier to add new features, modify existing ones, and maintain the system. - -A layered architecture is often used for large and complex systems, where the need for scalability and flexibility is high. Each layer in a layered architecture is responsible for a specific functionality and can be thought of as a "black box" with a well-defined interface. The layers communicate with each other through these interfaces, allowing for a clear separation of concerns. +A layered architecture organizes a system into horizontal layers, such as presentation, business logic, and data access, where each layer only communicates with the layer directly below or above it. This separation makes it easier to reason about and test each layer in isolation. It is a common structure for traditional enterprise applications, though strict layering can add overhead when a request needs to pass through every layer. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/mappers@ndUTgl2YBzOdu1MQKJocu.md b/roadmaps/software-design-architecture/content/mappers@ndUTgl2YBzOdu1MQKJocu.md index 2e9fa91c5..87318b669 100644 --- a/roadmaps/software-design-architecture/content/mappers@ndUTgl2YBzOdu1MQKJocu.md +++ b/roadmaps/software-design-architecture/content/mappers@ndUTgl2YBzOdu1MQKJocu.md @@ -1,8 +1,6 @@ # Mappers -Mappers are a pattern used in enterprise application development to provide a consistent and abstracted way to map between different data models. They act as an abstraction layer between the application and the data storage, providing a consistent and simple API for data transformation. - -A mapper is a component that can be used to convert data from one format or model to another. For example, a mapper can be used to convert data from a database model to a domain model, or from a domain model to a data transfer object (DTO). +A mapper converts data between two different representations, such as translating a database row into a domain object or converting a domain object into a format suitable for an API response. This separation keeps the domain model free of persistence or transport concerns, since it does not need to know how it will be stored or transmitted. Mappers are often used alongside repositories and DTOs to keep each layer of an application focused on its own representation of data. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/message-queues--streams@GAs6NHBkUgxan3hyPvVs7.md b/roadmaps/software-design-architecture/content/message-queues--streams@GAs6NHBkUgxan3hyPvVs7.md index 346de5083..99af5e81f 100644 --- a/roadmaps/software-design-architecture/content/message-queues--streams@GAs6NHBkUgxan3hyPvVs7.md +++ b/roadmaps/software-design-architecture/content/message-queues--streams@GAs6NHBkUgxan3hyPvVs7.md @@ -1,8 +1,6 @@ # Message Queues Streams -Message queues and streams are architectural patterns that are used to decouple different components of a system and enable asynchronous communication between them. - -Message Queues: A message queue is a software component that allows multiple systems or applications to communicate with each other by passing messages between them. Messages are stored in a queue, and each message is processed by a single consumer. This pattern is useful for systems where there is a high degree of variability in the rate of message production and consumption, and where the sender and receiver do not need to be active at the same time. Examples of message queue systems are Apache Kafka, RabbitMQ, and Amazon SQS. +Message queues and streams are infrastructure components that store and pass messages between producers and consumers, allowing them to operate independently and at different speeds. A queue typically delivers each message to one consumer and removes it once processed, while a stream keeps an ordered log of events that multiple consumers can read and replay. Tools like RabbitMQ, Kafka, and Amazon SQS implement these patterns to support asynchronous, decoupled communication between services. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/messaging@j9j45Auf60kIskyEMUGE3.md b/roadmaps/software-design-architecture/content/messaging@j9j45Auf60kIskyEMUGE3.md index 38a2e2f36..0e04f8183 100644 --- a/roadmaps/software-design-architecture/content/messaging@j9j45Auf60kIskyEMUGE3.md +++ b/roadmaps/software-design-architecture/content/messaging@j9j45Auf60kIskyEMUGE3.md @@ -1,12 +1,6 @@ # Messaging -Messaging is a key concept in several architectural styles, including event-driven architecture (EDA), microservices, and message-driven architecture (MDA). - -* Event-driven architecture (EDA) -* Microservices -* Message-driven architecture (MDA) - -In general, messaging is a powerful concept that allows for the decoupling and scalability of systems and it's used in different architectural styles to improve the flexibility and scalability of the system by allowing for loose coupling between components and making it easier to add new features or modify existing ones. +Messaging is a way for different parts of a distributed system to communicate by sending and receiving discrete pieces of data called messages, instead of calling each other directly. It decouples the sender from the receiver, since the sender does not need to know who will process the message or when. Common messaging patterns include event-driven communication and publish-subscribe, both often implemented with message brokers like RabbitMQ or Kafka. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/minimize-cyclomatic-complexity@qZzl0hAD2LkShsPql1IlZ.md b/roadmaps/software-design-architecture/content/minimize-cyclomatic-complexity@qZzl0hAD2LkShsPql1IlZ.md index b0dffd145..5f930e273 100644 --- a/roadmaps/software-design-architecture/content/minimize-cyclomatic-complexity@qZzl0hAD2LkShsPql1IlZ.md +++ b/roadmaps/software-design-architecture/content/minimize-cyclomatic-complexity@qZzl0hAD2LkShsPql1IlZ.md @@ -1,6 +1,6 @@ # Minimize Cyclomatic Complexity -Cyclomatic complexity measures the number of linearly independent paths through a program's source code. It's calculated based on the number of decision points (like `if`, `for`, `while`, `case`) within a function or code block. High cyclomatic complexity indicates code that is harder to understand, test, and maintain due to its increased number of possible execution paths. Reducing this complexity aims to simplify the control flow and logic within code, leading to more readable and reliable software. +Cyclomatic complexity measures the number of linearly independent paths through a program's source code. It's calculated based on the number of decision points (like `if`, `for`, `while`, `case`) within a function or code block. High cyclomatic complexity indicates code that is harder to understand, test, and maintain due to its increased number of possible execution paths. Reducing this complexity aims to simplify the control flow and logic within code, leading to more readable and reliable software. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/model-driven-design@0VO_-1g-TS29y0Ji2yCjc.md b/roadmaps/software-design-architecture/content/model-driven-design@0VO_-1g-TS29y0Ji2yCjc.md index 0368561e2..3dd5299c6 100644 --- a/roadmaps/software-design-architecture/content/model-driven-design@0VO_-1g-TS29y0Ji2yCjc.md +++ b/roadmaps/software-design-architecture/content/model-driven-design@0VO_-1g-TS29y0Ji2yCjc.md @@ -1,8 +1,6 @@ -# Model Driven Design +# Model-Driven Design -Model-driven design (MDD) is a software development methodology in which the design of a system is represented by a set of models, and the models are used to drive the development of the system. MDD is based on the idea that the design of a system can be represented by a set of models, and that these models can be used to generate the code for the system. - -The main advantage of using MDD is that it allows for a clear separation of concerns between the design and implementation of a system. The models represent the design of the system, and the code is generated from the models, which makes it easier to maintain and evolve the system. Additionally, MDD can also improve the quality of the code, as the models can be used to check for design errors and inconsistencies before the code is generated. +Model-Driven Design is a software development approach that emphasizes creating rigorous, conceptual models to represent the problem domain before writing any code. By focusing on these models, developers ensure that the software structure directly reflects the business logic and rules of the system. This method relies on using diagrams and formal specifications to define how objects interact and behave, which serves as the primary blueprint for the implementation. It allows teams to manage complex systems by keeping the design consistent and aligned with the requirements throughout the entire development process. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/monolithic@xYPR_X1KhBwdpqYzNJiuT.md b/roadmaps/software-design-architecture/content/monolithic@xYPR_X1KhBwdpqYzNJiuT.md index b1facaad8..91bb18c8e 100644 --- a/roadmaps/software-design-architecture/content/monolithic@xYPR_X1KhBwdpqYzNJiuT.md +++ b/roadmaps/software-design-architecture/content/monolithic@xYPR_X1KhBwdpqYzNJiuT.md @@ -1,8 +1,6 @@ # Monolithic -In software architecture, monolithic architecture is a design approach in which a software system is built as a single, integrated, and self-contained unit. In a monolithic architecture, all the components of the system are tightly coupled and depend on each other. This means that changes in one part of the system may affect other parts of the system. - -A monolithic architecture is often used for small to medium-sized systems, where the complexity of the system is manageable and the need for scalability and flexibility is not as high. In a monolithic architecture, the entire system is typically built, deployed, and executed as a single unit, which can make it easier to understand and manage the system. +A monolithic architecture builds an application as a single, unified codebase where all components, such as the user interface, business logic, and data access, run as one deployable unit. This simplifies development and deployment early on, since there is only one artifact to build and run. As the application grows, a monolith can become harder to maintain and scale, since a change in one part often requires redeploying the entire system. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/organize-code-by-actor-it-belongs-to@kp86Vc3uue3IxTN9B9p59.md b/roadmaps/software-design-architecture/content/organize-code-by-actor-it-belongs-to@kp86Vc3uue3IxTN9B9p59.md index d6045813e..e968bc24b 100644 --- a/roadmaps/software-design-architecture/content/organize-code-by-actor-it-belongs-to@kp86Vc3uue3IxTN9B9p59.md +++ b/roadmaps/software-design-architecture/content/organize-code-by-actor-it-belongs-to@kp86Vc3uue3IxTN9B9p59.md @@ -1,19 +1,6 @@ -# Organize Code by Actor It Belongs To +# Organize code by actor it belongs to -Organizing code by the actor it belongs to means structuring your codebase around the primary users, roles, or systems that interact with it. Instead of grouping code purely by technical layers (controllers, services, repositories), you group it by _who_ or _what_ uses the functionality. This improves cohesion, discoverability, and long-term maintainability. - -Some key ideas behind this approach include: - -* Actor-focused structure: Group related functionality by user roles, domains, or external systems (e.g., `admin`, `customer`, `payment-gateway`). -* High cohesion: Keep logic that changes for the same reason in the same place. -* Reduced coupling: Minimize dependencies between unrelated actors or domains. -* Clear ownership: Each module clearly represents a responsibility or business capability. -* Easier navigation: Developers can quickly find relevant code based on the actor they are working on. -* Scalability: The codebase grows more naturally as new actors or features are added. -* Improved testing: Actor-based modules are easier to test in isolation. -* Alignment with business logic: The structure mirrors real-world use cases and workflows. -* Better collaboration: Teams can own specific actors or domains. -* Cleaner boundaries: Encourages well-defined APIs between parts of the system. +Organizing code by the actor it belongs to involves grouping components, classes, or modules based on the specific business entities or users they serve. This approach aligns the physical structure of a codebase with the actual responsibilities and requirements of the stakeholders involved in the system. By separating elements according to their primary actor, developers can minimize the impact of changes, as modifications requested by one group of users only affect the files associated with their specific domain. This practice reduces coupling and helps maintain a clear mapping between business processes and technical implementations. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/orms@SYYulHfDceIyDkDT5fcqj.md b/roadmaps/software-design-architecture/content/orms@SYYulHfDceIyDkDT5fcqj.md index f25b5b82c..47f0d8f73 100644 --- a/roadmaps/software-design-architecture/content/orms@SYYulHfDceIyDkDT5fcqj.md +++ b/roadmaps/software-design-architecture/content/orms@SYYulHfDceIyDkDT5fcqj.md @@ -1,8 +1,6 @@ # ORMs -ORM stands for Object-Relational Mapping, it is a technique used in enterprise application development to map between the object-oriented programming model and the relational database model. It allows developers to work with objects in their code, while the ORM tool takes care of translating those objects into the appropriate database operations. - -ORMs are designed to abstract away the complexity of working with a relational database and allow developers to interact with the database using a higher-level, object-oriented API. They provide a set of libraries and tools that map the objects in the code to the tables and rows in the database, and vice versa. This allows developers to work with the data using a familiar object-oriented paradigm, rather than having to write complex SQL queries. +An Object-Relational Mapper, or ORM, translates data between a relational database and objects in an application's code, letting developers work with database records as regular objects instead of writing raw SQL. It handles tasks like generating queries, mapping rows to objects, and managing relationships between tables. Popular ORMs include Hibernate for Java, SQLAlchemy for Python, and Entity Framework for .NET, though they can introduce performance overhead compared to hand-written queries for complex operations. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/peer-to-peer@Cf9Z2wxBcbnNg_q9PA6xA.md b/roadmaps/software-design-architecture/content/peer-to-peer@Cf9Z2wxBcbnNg_q9PA6xA.md index 311a906b1..2aaa638ae 100644 --- a/roadmaps/software-design-architecture/content/peer-to-peer@Cf9Z2wxBcbnNg_q9PA6xA.md +++ b/roadmaps/software-design-architecture/content/peer-to-peer@Cf9Z2wxBcbnNg_q9PA6xA.md @@ -1,8 +1,6 @@ # Peer to Peer -Peer-to-peer (P2P) architecture is a distributed computing architecture in which each node (peer) in the network acts as both a client and a server. In P2P architecture, there is no central authority or server that manages the network, and each node communicates directly with other nodes to exchange information, share resources, and perform computations. - -The main advantage of using P2P architecture is that it allows for a more decentralized and fault-tolerant system. As there is no central authority, there is no single point of failure, and the network can continue to function even if some nodes fail. Additionally, P2P architecture can also improve scalability as the number of nodes in the network increases. +Peer-to-peer is a distributed architecture where each node, called a peer, acts as both a client and a server, sharing resources directly with other peers instead of relying on a central server. This removes a single point of failure and can spread load across many machines. File-sharing networks and some blockchain systems use this style, though coordinating consistency and security across peers is harder without central control. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/policy-vs-detail@b_PvjjL2ZpEKETa5_bd0v.md b/roadmaps/software-design-architecture/content/policy-vs-detail@b_PvjjL2ZpEKETa5_bd0v.md index 2795ebaba..102d1daeb 100644 --- a/roadmaps/software-design-architecture/content/policy-vs-detail@b_PvjjL2ZpEKETa5_bd0v.md +++ b/roadmaps/software-design-architecture/content/policy-vs-detail@b_PvjjL2ZpEKETa5_bd0v.md @@ -1,7 +1,3 @@ # Policy vs Detail -In software architecture, the distinction between **policy** and **detail** refers to the separation of high-level decisions and low-level implementation details. - -Policy refers to the high-level decisions that define the overall behavior and structure of the system. These decisions include things like the overall architecture, the system's interface, and the major components and their interactions. Policy decisions are often made by architects and designers, and they set the overall direction for the system. - -Detail refers to the low-level implementation details that are required to implement the policy decisions. These include things like the specific algorithms, data structures, and code that make up the system's components. Details are often implemented by developers and are responsible for the actual functioning of the system. \ No newline at end of file +Policy and detail represent a fundamental separation between the core logic of an application and the specific implementation mechanisms that support it. Policies define the high-level business rules, domain entities, and operational requirements that dictate what an application should accomplish. In contrast, details encompass the low-level components like database drivers, user interface frameworks, external APIs, and hardware configurations that provide the environment for those policies to run. Keeping these concepts separate ensures that business logic remains independent of the specific tools used to execute it, allowing developers to change or upgrade technical infrastructure without altering the core functionality. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/polymorphism@4DVW4teisMz8-58XttMGt.md b/roadmaps/software-design-architecture/content/polymorphism@4DVW4teisMz8-58XttMGt.md index b6433b1bf..fc874d901 100644 --- a/roadmaps/software-design-architecture/content/polymorphism@4DVW4teisMz8-58XttMGt.md +++ b/roadmaps/software-design-architecture/content/polymorphism@4DVW4teisMz8-58XttMGt.md @@ -1,11 +1,6 @@ # Polymorphism -Polymorphism is a concept in object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common parent class. This is achieved by defining a common interface for all classes that need to be treated polymorphically. The word polymorphism is derived from Greek, "poly" means many and "morph" means form. - -There are two types of polymorphism: - -* Compile-time polymorphism (also called static polymorphism or early binding) occurs when the type of the object that is going to be acted upon is determined at compile-time. This is achieved through method overloading, which allows multiple methods to have the same name but different parameters within the same class. -* Run-time polymorphism (also called dynamic polymorphism or late binding) occurs when the type of the object is determined at run-time. This is achieved through method overriding, which allows a child class to provide a specific implementation of a method that is already defined in its parent class. +Polymorphism is a core principle in object-oriented programming that allows objects of different classes to be treated as instances of a common base class. It enables a single interface to represent different underlying forms, meaning a method call can behave differently depending on the specific object it is acting upon. By utilizing techniques like method overriding and overloading, developers can write flexible code that works with various data types through a unified structure. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/posa-patterns@6VoDGFOPHj5p_gvaZ8kTt.md b/roadmaps/software-design-architecture/content/posa-patterns@6VoDGFOPHj5p_gvaZ8kTt.md index 655794d8a..159a0df62 100644 --- a/roadmaps/software-design-architecture/content/posa-patterns@6VoDGFOPHj5p_gvaZ8kTt.md +++ b/roadmaps/software-design-architecture/content/posa-patterns@6VoDGFOPHj5p_gvaZ8kTt.md @@ -1,13 +1,6 @@ -# POSA Patterns +# PoSA Patterns -POSA (Pattern-Oriented Software Architecture) is a set of design patterns for developing software systems that can scale and adapt to changing requirements. These patterns were first described in the book "Patterns of Scalable, Reliable Services" by Kevin Hoffman. - -POSA patterns are divided into four categories: - -* Partitioning Patterns -* Placement Patterns -* Routing Patterns -* Federation Patterns +Pattern-Oriented Software Architecture (PoSA) patterns provide a standardized way to describe and organize recurring architectural structures and design solutions within complex software systems. These patterns function as proven blueprints that help developers structure the overall layout of an application, handle communication between components, and manage distributed systems. By offering a common vocabulary and set of templates for high-level design, PoSA patterns guide the process of decomposing a system into smaller, manageable parts that work together to meet functional and quality requirements. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/program-against-abstractions@UZeY36dABmULhsHPhlzn_.md b/roadmaps/software-design-architecture/content/program-against-abstractions@UZeY36dABmULhsHPhlzn_.md index 24fea401d..a6feec3d7 100644 --- a/roadmaps/software-design-architecture/content/program-against-abstractions@UZeY36dABmULhsHPhlzn_.md +++ b/roadmaps/software-design-architecture/content/program-against-abstractions@UZeY36dABmULhsHPhlzn_.md @@ -1,8 +1,6 @@ -# Program Against Abstractions +# Program against abstractions -Programming against abstractions is a programming principle that suggests that code should be written in such a way that it is not tied to specific implementations, but rather to abstractions. This is accomplished by defining interfaces or abstract classes that define the behavior of a group of related classes without specifying their implementation. - -Programming against abstractions allows for more flexibility in the code. When changes are needed, they can be made to the implementation of the abstractions without affecting the code that uses them. This makes it easier to understand, test, and maintain the code. +Programming against abstractions involves interacting with interfaces or abstract base classes rather than concrete implementations. This approach allows a system to remain decoupled from the specific details of how a task is performed, enabling developers to swap or modify underlying components without affecting the rest of the application. By focusing on what an object does rather than how it is specifically constructed, code becomes more flexible, easier to maintain, and simpler to test. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/programming-paradigms@RgYq3YOJhPGSf5in1Rcdp.md b/roadmaps/software-design-architecture/content/programming-paradigms@RgYq3YOJhPGSf5in1Rcdp.md index dab0e5614..3f457f9e8 100644 --- a/roadmaps/software-design-architecture/content/programming-paradigms@RgYq3YOJhPGSf5in1Rcdp.md +++ b/roadmaps/software-design-architecture/content/programming-paradigms@RgYq3YOJhPGSf5in1Rcdp.md @@ -1,12 +1,6 @@ # Programming Paradigms -A programming paradigm is a fundamental style or approach to solving problems using a programming language. Different programming paradigms provide different ways of organizing and structuring code, and have different strengths and weaknesses. Some of the most common programming paradigms include: - -* Imperative programming -* Functional programming -* Object-oriented programming -* Logic programming -* Declarative programming +A programming paradigm is a fundamental style or approach to structuring and writing code, such as object-oriented, functional, or procedural programming. Each paradigm offers different ways to organize logic, manage state, and handle control flow, and many languages support more than one paradigm. Understanding different paradigms helps developers choose the right approach for a given problem rather than forcing every solution into a single style. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/programming-paradigms@TDhTYdEyBuOnDKcQJzTAk.md b/roadmaps/software-design-architecture/content/programming-paradigms@TDhTYdEyBuOnDKcQJzTAk.md index dab0e5614..c1a98f049 100644 --- a/roadmaps/software-design-architecture/content/programming-paradigms@TDhTYdEyBuOnDKcQJzTAk.md +++ b/roadmaps/software-design-architecture/content/programming-paradigms@TDhTYdEyBuOnDKcQJzTAk.md @@ -1,12 +1,6 @@ # Programming Paradigms -A programming paradigm is a fundamental style or approach to solving problems using a programming language. Different programming paradigms provide different ways of organizing and structuring code, and have different strengths and weaknesses. Some of the most common programming paradigms include: - -* Imperative programming -* Functional programming -* Object-oriented programming -* Logic programming -* Declarative programming +Programming paradigms are fundamental styles or approaches used to structure and organize computer programs. Each paradigm represents a distinct way of thinking about the execution of code, dictating how developers model problems and manage the state of an application. Common examples include procedural programming, which focuses on a sequence of instructions; object-oriented programming, which organizes code around data objects; and functional programming, which emphasizes the use of mathematical functions and immutable data. These approaches provide the conceptual framework that guides how software systems are designed and maintained. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/publish-subscribe@SX4vOVJY9slOXGwX_q1au.md b/roadmaps/software-design-architecture/content/publish-subscribe@SX4vOVJY9slOXGwX_q1au.md index 6edca8f99..f58c3aef0 100644 --- a/roadmaps/software-design-architecture/content/publish-subscribe@SX4vOVJY9slOXGwX_q1au.md +++ b/roadmaps/software-design-architecture/content/publish-subscribe@SX4vOVJY9slOXGwX_q1au.md @@ -1,8 +1,6 @@ # Publish Subscribe -The publish-subscribe pattern is a messaging pattern in which a publisher sends a message to a topic, and any number of subscribers can subscribe to that topic to receive the message. The publish-subscribe pattern is also known as the "observer pattern" and is a way of implementing communication between different parts of an application in a decoupled way. - -The main advantage of using the publish-subscribe pattern is that it allows for a clear separation of concerns between the publisher and the subscribers, and it can improve the flexibility and scalability of the system. Additionally, it allows for loose coupling between components, meaning that the publisher and subscribers are not aware of each other's existence, and can be developed, deployed, and scaled independently. +Publish-subscribe is a messaging pattern where senders, called publishers, send messages to a channel or topic without knowing who will receive them. Receivers, called subscribers, express interest in specific topics and receive only the messages published to those topics. A message broker sits between publishers and subscribers, routing messages and allowing multiple subscribers to receive the same message independently. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/repositories@8y0ot5sbplUIUyXe9gvc8.md b/roadmaps/software-design-architecture/content/repositories@8y0ot5sbplUIUyXe9gvc8.md index c0b063e8a..ac98a6514 100644 --- a/roadmaps/software-design-architecture/content/repositories@8y0ot5sbplUIUyXe9gvc8.md +++ b/roadmaps/software-design-architecture/content/repositories@8y0ot5sbplUIUyXe9gvc8.md @@ -1,8 +1,6 @@ # Repositories -Repositories are a pattern used in enterprise application development to provide a consistent and abstracted way to access data storage. Repositories act as an abstraction layer between the application and the data storage, providing a consistent and simple API for data access and manipulation. - -A repository is a pattern that can be used to organize the data access code and encapsulate the logic of retrieving and storing objects. Repositories provide a way to separate the concerns of the data access from the rest of the application, allowing the application code to be written against an interface and not a specific data storage technology. +A repository is a pattern that provides an abstraction over data storage, exposing methods to retrieve, add, update, or remove objects without exposing the details of how that data is persisted. Application code interacts with the repository's interface instead of writing database queries directly, which makes it easier to change the underlying storage technology or write tests using a fake implementation. Repositories are commonly paired with domain models in Domain-Driven Design. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/scope--visibility@b-YIbw-r-nESVt_PUFQeq.md b/roadmaps/software-design-architecture/content/scope--visibility@b-YIbw-r-nESVt_PUFQeq.md index c402543a4..7fcc7bfc7 100644 --- a/roadmaps/software-design-architecture/content/scope--visibility@b-YIbw-r-nESVt_PUFQeq.md +++ b/roadmaps/software-design-architecture/content/scope--visibility@b-YIbw-r-nESVt_PUFQeq.md @@ -1,9 +1,3 @@ -# Scope Visibility +# Scope and Visibility -Scope visibility refers to the accessibility or visibility of variables, functions, and other elements in a program, depending on the context in which they are defined. In object-oriented programming (OOP), scope visibility is controlled through the use of access modifiers, such as "public," "private," and "protected." - -* Public: A public element can be accessed from anywhere in the program, both within the class and outside of it. -* Private: A private element can only be accessed within the class in which it is defined. It is not accessible to other classes, even if they inherit from the class. -* Protected: A protected element can only be accessed within the class and its subclasses. - -There are variations of scope visibility based on the programming language, but these are the most common. \ No newline at end of file +Scope and visibility define the accessibility of variables, methods, and classes within a codebase. Scope refers to the specific region of the program where a particular identifier is valid and can be referenced. Visibility, often managed through access modifiers like public, private, or protected, determines whether these members can be accessed from other parts of the application or restricted to specific classes and subclasses. Controlling these boundaries helps developers hide internal implementation details and prevent accidental modification of sensitive data. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/serverless-architecture@5WSvAA3h3lmelL53UJSMy.md b/roadmaps/software-design-architecture/content/serverless-architecture@5WSvAA3h3lmelL53UJSMy.md index e90f23947..5d038a91e 100644 --- a/roadmaps/software-design-architecture/content/serverless-architecture@5WSvAA3h3lmelL53UJSMy.md +++ b/roadmaps/software-design-architecture/content/serverless-architecture@5WSvAA3h3lmelL53UJSMy.md @@ -1,8 +1,6 @@ # Serverless Architecture -Serverless architecture is a design pattern that allows developers to build and run applications and services without having to provision and manage servers. Instead, these applications and services are executed in a fully managed environment, such as AWS Lambda, Azure Functions, or Google Cloud Functions, where the infrastructure and scaling are handled automatically by the cloud provider. - -This architecture pattern mainly focuses on the business logic and event-driven execution, rather than on server management. It allows developers to write and deploy code in small, single-purpose functions that are triggered by specific events, such as changes in a database or the arrival of new data in a stream. +Serverless architecture lets developers build and run applications without managing the underlying servers, since a cloud provider automatically provisions, scales, and manages the infrastructure. Code runs in stateless functions that execute in response to events, and the provider charges based on actual usage rather than reserved capacity. This model reduces operational overhead but can introduce challenges around cold start latency and vendor lock-in. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/soa@FysFru2FJN4d4gj11gv--.md b/roadmaps/software-design-architecture/content/soa@FysFru2FJN4d4gj11gv--.md index 1f9314aef..1a71d6c76 100644 --- a/roadmaps/software-design-architecture/content/soa@FysFru2FJN4d4gj11gv--.md +++ b/roadmaps/software-design-architecture/content/soa@FysFru2FJN4d4gj11gv--.md @@ -1,6 +1,6 @@ # SOA -SOA (Service-Oriented Architecture) is an architectural pattern that is used to design and organize software systems as a collection of services that can be accessed over a network, these services are autonomous, self-contained units of functionality that can be reused and combined to create new functionality. SOA services are designed to be loosely coupled, meaning that they do not depend on the implementation details of other services, they communicate with each other through well-defined interfaces, usually using a protocol such as HTTP or SOAP. SOA provides several advantages over other architectural patterns, such as reusability, modularity, interoperability, and scalability. It can be implemented using a variety of technologies, such as Web Services, REST, and microservices. +Service-Oriented Architecture, or SOA, structures an application as a collection of loosely coupled services that communicate over a network, typically through standardized protocols. Each service exposes a well-defined interface and can be reused across different applications within an organization. SOA often relies on an enterprise service bus to manage communication, routing, and integration between services, which distinguishes it from the more independent, lightweight services used in microservices. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/solid@3XckqZA--knUb8IYKOeVy.md b/roadmaps/software-design-architecture/content/solid@3XckqZA--knUb8IYKOeVy.md index 848ea551e..29f6cd495 100644 --- a/roadmaps/software-design-architecture/content/solid@3XckqZA--knUb8IYKOeVy.md +++ b/roadmaps/software-design-architecture/content/solid@3XckqZA--knUb8IYKOeVy.md @@ -1,12 +1,6 @@ -# SOLID +# SOLID Principles -SOLID is an acronym that stands for five principles of object-oriented software development, which were first introduced by Robert C. Martin in the early 2000s. These principles are: - -* Single Responsibility Principle (SRP) -* Open/Closed Principle (OCP) -* Liskov Substitution Principle (LSP) -* Interface Segregation Principle (ISP) -* Dependency Inversion Principle (DIP) +SOLID is a set of five design guidelines intended to make software designs more understandable, flexible, and maintainable. These principles include the Single Responsibility Principle, Open/Closed Principle, Liskov Substitution Principle, Interface Segregation Principle, and Dependency Inversion Principle. Adopting these standards helps developers reduce code complexity, minimize tight coupling between components, and facilitate easier testing and future modifications. By applying these concepts, software systems become more robust and adaptable to evolving requirements. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/structural@86Jw9kMBD7YP5nTV5jTz-.md b/roadmaps/software-design-architecture/content/structural@86Jw9kMBD7YP5nTV5jTz-.md index 2c4ff7068..65862bbf6 100644 --- a/roadmaps/software-design-architecture/content/structural@86Jw9kMBD7YP5nTV5jTz-.md +++ b/roadmaps/software-design-architecture/content/structural@86Jw9kMBD7YP5nTV5jTz-.md @@ -1,14 +1,3 @@ # Structural -Structural architecture in software refers to the organization and design of the components of a software system, and how they interact with each other. It deals with the physical organization of the system, and the relationships between the different components. - -There are several different structural architecture patterns and styles that can be used to design software systems, including: - -* Monolithic: where the system is built as a single, integrated, and self-contained unit. -* Layered: where the system is divided into a set of layers, each of which has a specific responsibility and communicates with the other layers through well-defined interfaces. -* Microservices: where the system is built as a collection of small, independent, and loosely-coupled services. -* Event-driven: where the system reacts to specific events that occur, rather than being continuously polled for changes. -* Client-Server: where a client sends requests to a server, and the server responds to those requests -* Peer-to-Peer: where each node in the network acts as both a client and a server -* Component-based: where the system is composed of reusable and independent software components -* Domain-Driven: where the system is organized around the core business domain and business entities. \ No newline at end of file +Structural architectural styles focus on how a system's components are organized internally, such as how code is divided into layers, modules, or units. They determine how responsibilities are separated within a single application, as opposed to how the application communicates across a network. Common structural styles include monolithic, layered, and component-based design. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/tell-dont-ask@0rGdh72HjqPZa2bCbY9Gz.md b/roadmaps/software-design-architecture/content/tell-dont-ask@0rGdh72HjqPZa2bCbY9Gz.md index 2946650bf..0dc67af27 100644 --- a/roadmaps/software-design-architecture/content/tell-dont-ask@0rGdh72HjqPZa2bCbY9Gz.md +++ b/roadmaps/software-design-architecture/content/tell-dont-ask@0rGdh72HjqPZa2bCbY9Gz.md @@ -1,25 +1,6 @@ -# Tell, Don’t Ask +# Tell, Don't Ask -The Tell, Don’t Ask principle emphasizes that objects should be told what to do rather than being queried for their state and having decisions made externally. This promotes encapsulation and reduces coupling by keeping logic within the objects that own the data. - -Key Concepts ------------- - -* Instead of pulling data out of objects to make decisions, push the behavior into the object itself. -* Objects should be responsible for their own logic and state management. - -Asking style (bad): - - if (user.profile.isComplete()) { - // allow checkout - } - - -Telling style (good): - - if (user.canCheckout()) { - // allow checkout - } +Tell, don't ask is a principle that encourages object-oriented design where you tell an object to perform an action rather than asking for its internal state to make decisions yourself. Instead of retrieving data from an object using getter methods to perform logic externally, you encapsulate that logic within the object itself by providing a command or a method. This approach promotes better encapsulation by keeping the internal data hidden and ensuring that the object responsible for the data is also responsible for the behavior associated with it. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/tests-should-be-fast-and-independent@mzt7fvx6ab3tmG1R1NcLO.md b/roadmaps/software-design-architecture/content/tests-should-be-fast-and-independent@mzt7fvx6ab3tmG1R1NcLO.md index 3a6025b93..441e302ca 100644 --- a/roadmaps/software-design-architecture/content/tests-should-be-fast-and-independent@mzt7fvx6ab3tmG1R1NcLO.md +++ b/roadmaps/software-design-architecture/content/tests-should-be-fast-and-independent@mzt7fvx6ab3tmG1R1NcLO.md @@ -1,23 +1,6 @@ -# Tests Should Be Fast and Independent +# Tests should be fast and independent -Fast and independent tests are a cornerstone of reliable and maintainable software. They enable developers to run tests frequently, get quick feedback, and trust the results. When tests are slow or tightly coupled to each other or external systems, they become a bottleneck and reduce confidence in the codebase. - -Well-designed tests focus on validating behavior in isolation and execute quickly enough to be run as part of everyday development. - -Some of the key principles of fast and independent tests include: - -* Speed: Tests should execute quickly so they can be run frequently during development. -* Independence: Each test should run in isolation and not depend on the outcome or state of other tests. -* Determinism: Tests should produce the same result every time they are run. -* Isolation: External dependencies (databases, APIs, file systems, time) should be mocked or stubbed. -* Single Responsibility: Each test should verify one behavior or scenario. -* Easy Setup and Teardown: Tests should have minimal and clear setup logic. -* Reliability: Tests should fail only when the code under test is broken, not due to environment issues. -* Automation Friendly: Tests should be easy to run in CI/CD pipelines without special configuration. -* Maintainability: Tests should be easy to read, understand, and update as the code evolves. -* Feedback-Oriented: Test failures should provide clear and actionable feedback. - -Fast and independent tests improve developer productivity, encourage refactoring, and act as living documentation for the system’s behavior. +Tests should be fast and independent refers to the practice of ensuring that a test suite executes quickly and that each individual test can run in any order without relying on the state of another. Fast tests provide immediate feedback during development, encouraging developers to run them frequently throughout the coding process. Independence ensures that the outcome of one test does not affect the results of others, which prevents cascading failures and makes it significantly easier to isolate and debug specific issues when a test fails. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/use-correct-constructs@S1m7ty7Qrzu1rr4Jl-WgM.md b/roadmaps/software-design-architecture/content/use-correct-constructs@S1m7ty7Qrzu1rr4Jl-WgM.md index 8031b1283..6f37ac28b 100644 --- a/roadmaps/software-design-architecture/content/use-correct-constructs@S1m7ty7Qrzu1rr4Jl-WgM.md +++ b/roadmaps/software-design-architecture/content/use-correct-constructs@S1m7ty7Qrzu1rr4Jl-WgM.md @@ -1,9 +1,3 @@ # Use Correct Constructs -In the context of clean code principles, "using correct constructs" refers to using appropriate programming constructs, such as loops, conditionals, and functions, in a way that makes the code easy to understand, maintain, and modify. - -When using correct constructs, the code should be organized in a logical and intuitive way, making use of appropriate control flow statements and data structures to accomplish the task at hand. This also means that the code should avoid using unnecessary or overly complex constructs that make the code harder to understand or reason about. - -Additionally, correct constructs also means to use the right constructs for the right problem, for example, if you want to iterate over an array, use a for loop instead of recursion and also, you should avoid using global variables and instead use function arguments and return values to pass data between different parts of the code. - -By using correct constructs, the code will be more readable, more maintainable, and less prone to bugs, making it easier for other developers to understand, debug and extend the code. \ No newline at end of file +Using correct constructs involves selecting the most appropriate programming language features, data structures, and syntax to express a specific logic clearly and efficiently. This practice focuses on avoiding the misuse of language capabilities, such as using a loop when a built-in functional method is available or picking an inefficient data type for a simple task. By adhering to idiomatic patterns, developers create code that is predictable, easier to debug, and more readable for other team members. \ No newline at end of file diff --git a/roadmaps/software-design-architecture/content/usecases@gQ7Xj8tsl6IlCcyJgSz46.md b/roadmaps/software-design-architecture/content/usecases@gQ7Xj8tsl6IlCcyJgSz46.md index 9494e2d84..c52a3e114 100644 --- a/roadmaps/software-design-architecture/content/usecases@gQ7Xj8tsl6IlCcyJgSz46.md +++ b/roadmaps/software-design-architecture/content/usecases@gQ7Xj8tsl6IlCcyJgSz46.md @@ -1,15 +1,6 @@ # Use Cases -Use Cases are a pattern used in enterprise application development to represent the functional requirements of a system. They describe the interactions between the system and its users, and the steps that are required to accomplish a specific goal. Use cases are a way to capture the requirements of the system in a way that is easily understood by both the development team and the stakeholders. - -A use case is a description of a sequence of actions that a system performs in response to a request from a user, in order to achieve a specific goal. A use case typically includes: - -* The actor (user) who initiates the action -* The goal that the actor wants to achieve -* The steps required to achieve the goal, including any alternative paths or error conditions -* The expected outcome of the interaction - -Use cases are often used to drive the design and development of the system, as they provide a clear and detailed understanding of the requirements. +A use case describes a specific interaction or process that a system supports to fulfill a user's goal, often expressed as a single class or function that orchestrates the steps needed to complete that goal. It sits between the presentation layer and the domain model, coordinating calls to entities, repositories, and other services without containing the core business rules itself. This separation keeps business logic testable and independent from how a request enters the system, whether through a web request, a command line, or an API call. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/value-objects@Ks6njbfxOHiZ_TrJDnVtk.md b/roadmaps/software-design-architecture/content/value-objects@Ks6njbfxOHiZ_TrJDnVtk.md index b375861f4..89bac17ae 100644 --- a/roadmaps/software-design-architecture/content/value-objects@Ks6njbfxOHiZ_TrJDnVtk.md +++ b/roadmaps/software-design-architecture/content/value-objects@Ks6njbfxOHiZ_TrJDnVtk.md @@ -1,8 +1,6 @@ # Value Objects -Value Objects are a pattern used in enterprise application development to represent simple, immutable values that are used to model domain concepts. They are typically used to encapsulate data that is not an entity, but is important to the domain. - -A Value Object is defined by its value rather than its identity, meaning that two Value Objects with the same value are considered to be equal, regardless of their identity. +A value object is an object defined entirely by its attributes rather than by a unique identity, meaning two value objects with the same attributes are considered equal. Examples include a date range, a monetary amount, or a coordinate pair. Value objects are typically immutable, so once created, their values do not change, which makes them easier to reason about and share safely across a codebase. Visit the following resources to learn more: diff --git a/roadmaps/software-design-architecture/content/yagni@eEO-WeNIyjErBE53n8JsD.md b/roadmaps/software-design-architecture/content/yagni@eEO-WeNIyjErBE53n8JsD.md index a3ddc67b4..8e43b5263 100644 --- a/roadmaps/software-design-architecture/content/yagni@eEO-WeNIyjErBE53n8JsD.md +++ b/roadmaps/software-design-architecture/content/yagni@eEO-WeNIyjErBE53n8JsD.md @@ -1,8 +1,6 @@ # YAGNI -YAGNI (You Ain't Gonna Need It) is a software development principle that suggests that developers should not add functionality to a codebase unless it is immediately necessary. The idea is to avoid creating unnecessary complexity in the codebase by only adding features that are actually needed. - -The YAGNI principle is closely related to the Single Responsibility Principle (SRP) and the Open-Closed Principle (OCP), which are part of the SOLID principles. YAGNI aims to keep the codebase as simple as possible by avoiding the creation of unnecessary abstractions and functionality. +YAGNI, which stands for "You Ain't Gonna Need It," is a principle in software development that suggests programmers should not add functionality until it is actually necessary. It encourages developers to focus only on the requirements at hand rather than attempting to predict future needs that may never arise. By avoiding the implementation of speculative features, the codebase remains simpler, easier to maintain, and less cluttered with unnecessary code. Visit the following resources to learn more: