<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Rafael Ritter on Medium]]></title>
        <description><![CDATA[Stories by Rafael Ritter on Medium]]></description>
        <link>https://medium.com/@rafaelritter?source=rss-9a1a8ffdb99e------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*AEDm6o4UCYwJXOpfZhOn7g.jpeg</url>
            <title>Stories by Rafael Ritter on Medium</title>
            <link>https://medium.com/@rafaelritter?source=rss-9a1a8ffdb99e------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 01:43:37 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@rafaelritter/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Domain Event: The Missing Building Block]]></title>
            <link>https://rafaelritter.medium.com/domain-event-the-missing-building-block-17858a7b99af?source=rss-9a1a8ffdb99e------2</link>
            <guid isPermaLink="false">https://medium.com/p/17858a7b99af</guid>
            <category><![CDATA[event-sourcing]]></category>
            <category><![CDATA[domain-events]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[cqrs]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <dc:creator><![CDATA[Rafael Ritter]]></dc:creator>
            <pubDate>Mon, 07 Jun 2021 16:38:37 GMT</pubDate>
            <atom:updated>2021-06-07T16:38:37.967Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Domain Events</strong></h3><p>Domain-Driven Design (DDD) is a pretty broad subject. It ranges from the higher-level strategic design concepts all the way down to its building blocks. The building blocks of DDD consist of patterns such as aggregates, services, entities, value objects, repositories and factories. These patterns not only help us create richer domain models, but they also facilitate communication about software design, since these few words convey so much knowledge in such a concise way that, when they are used, engineers immediately get context regarding what is being talked about.</p><p>That’s all well and good. There used to be a fundamental problem with the building blocks, though. The problem was the original list was incomplete. When Eric Evans wrote the blue book, he missed an essential building block that only came up later: the domain event. [1]</p><p>Now, before talking about domain events, let’s first simply define what events are, without the domain part. There are two main characteristics that define events: first, they have already happened; and secondly, as a result, they cannot be changed. In other words, events are immutable facts about the past. If we were building a board game, for example, we could design objects such as GameStartedEvent and MovePlayedEvent.</p><p>Okay, now we know what events are. But what are domain events? Domain events are simply events that belong to the domain model. If you are wondering how to distinguish between domain events and other events, just ask yourself: do domain experts care about it? If the event is not relevant to the business at all, then it’s not a domain event.</p><p>The next question that comes up is: why are domain events necessary? Why are they considered an important piece that was missing from the building blocks of domain modeling? The need for domain events often arises in distributed systems, like microservices architectures. When a microservice updates its state, other services might be interested in that change. A way of solving this is for that service to publish a domain event to which interested services can subscribe. This helps decoupling services as they are only communicating through domain events.</p><p>Even though the domain event pattern helps with decoupling, we need to be careful when applying this pattern. We have to remember that the contract of a service is not only its REST API. Given that domain events are visible from outside the service, they are part of the contract of that service as well. Therefore, changes to the event affect all consumers of that event, and not just the event producer. That means usual SOA governance practices apply, such as contract versioning, testing and documentation.</p><p>Besides its potential benefits, the domain event pattern is not only valuable in and of itself, but also necessary for implementing other patterns. One of the patterns that require the use of domain events is event sourcing.</p><h3><strong>Event Sourcing</strong></h3><p>Event sourcing is a completely different programming model compared to what developers are usually used to. It requires a strong paradigm shift and a substantial shift in thinking. Instead of the usual in-place updates that developers are allowed to perform when they want to change the state of the application, when applying event sourcing, they are only allowed to add new events, and never to alter what was recorded before. That is in accordance with the definition of event. So, in this paradigm, domain events become first-class citizens. The domain events are the source of truth. Thus, in event-sourced systems, the state of the application is maintained as a sequence of immutable facts (the domain events), which are persisted in a store of data called the event store. The event store is generally implemented as an append-only log.</p><p>Despite requiring a very different mindset compared to traditional programming, the event sourcing model brings several benefits to the table. First of all, since domain events are the source of truth, it enables loosely coupled microservices architectures, in which services distribute their data through those events. Secondly, we are always able to replay the events in the same order in which they actually happened, which can help with troubleshooting and bug fixing, since we can reprocess the events after bugs are fixed. Also, another great advantage of the event store is that it enables a forward-compatible architecture. That means we can build new applications in the future that depend on domain events that have already been implemented, and we can plug those new applications in the event store so they can process all events from the very beginning of history. Besides all of that, there is also a problem that event-sourced systems, unlike other systems, don’t have to struggle with: the problem of dual writes. Because the domain events are the single source of truth, there is no dual write in event-sourced systems.</p><p>Event sourcing does bring lots of benefits as well as architectural options, but we do have to remember that there is no silver bullet. In addition to the more complex programming model and its higher learning curve, event sourcing also makes it more difficult to query the current state of the application, given that it requires transforming the domain events into something suitable to query. Let’s talk about another pattern that helps us with just that.</p><h3><strong>CQRS</strong></h3><p>In microservices architectures, data is distributed and each service (ideally) has its own database. Yet, there is still relationship between data. So how do you perform a query that joins data from multiple services? Furthermore, in an event-sourced system, the event store is not easily queryable by the application.</p><p>CQRS, which stands for Command-Query Responsibility Segregation, is a pattern that uses domain events in order to build read-only views of data, known as projections. So the solution it proposes is to duplicate data and to design the different replicas of the data to support specific queries. Different services keep their replicas up-to-date by subscribing to the domain events published by the owner of the data. Since the events produced in one bounded context may be consumed in other bounded contexts, different models are allowed to be used. [2] And that’s one of the options we get by segregating the commands responsibilities from the queries’: we can have different models for reading and writing. While the command handler is generally concerned about validating the commands and satisfying the business rules, the query handler is concerned about optimizing reads according to the access patterns of the application.</p><p>Applying the CQRS pattern provides loose coupling between reads and writes, which in turn leads to scalability and performance gains as reads and writes can be scaled independently. Not only that, but the various projections themselves can scale independently, and each of them can use the storage technology that best suits their application’s access patterns, effectively enabling polyglot persistence. A search application, for example, may store its projection in Elasticsearch, while another one may cache it in Redis.</p><p>An important aspect of this pattern to keep in mind, however, is that the subscription to domain events and the subsequent update of projections are asynchronous processes. Therefore, the CQRS projections are eventually consistent. This might or might not be an issue. It will depend on the application requirements and the needs of its users.</p><h3><strong>Code</strong></h3><p>As Linus Torvalds once said, “Talk is cheap. Show me the code.” I’ve implemented this tic-tac-toe application using event sourcing. [3] I used Kafka as the event store, saving all domain events in a Kafka topic. Here is the architecture:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mg-X4L00o_2N06YhH2-4ng.png" /></figure><p><strong>Figure 1</strong>: Event-Sourced Tic-Tac-Toe’s Architecture</p><h3><strong>Conclusion</strong></h3><p>I cannot stress this enough: there is no silver bullet in software design. The domain event pattern is indeed a critical building block of DDD that was missing from the original list, and it does open up very interesting possibilities regarding domain-driven modeling and design. But its potential benefits do not free us from doing proper requirements assessment, comparing potential solutions, analyzing the trade-offs and understanding whether they pay off or not in order to make informed decisions.</p><h3><strong>References</strong></h3><ol><li><a href="https://www.youtube.com/watch?v=lE6Hxz4yomA">https://www.youtube.com/watch?v=lE6Hxz4yomA</a></li><li><a href="https://rafaelritter.medium.com/ddd-model-integrity-patterns-36d0e8ac9561">https://rafaelritter.medium.com/ddd-model-integrity-patterns-36d0e8ac9561</a></li><li><a href="https://github.com/rafaritter44/java-pocs/tree/master/event-sourcing">https://github.com/rafaritter44/java-pocs/tree/master/event-sourcing</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=17858a7b99af" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Core Domain Distillation]]></title>
            <link>https://rafaelritter.medium.com/core-domain-distillation-a35e08ec9392?source=rss-9a1a8ffdb99e------2</link>
            <guid isPermaLink="false">https://medium.com/p/a35e08ec9392</guid>
            <category><![CDATA[domain-driven-design]]></category>
            <category><![CDATA[software-design]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[core-domain]]></category>
            <dc:creator><![CDATA[Rafael Ritter]]></dc:creator>
            <pubDate>Mon, 26 Apr 2021 11:59:57 GMT</pubDate>
            <atom:updated>2021-04-26T14:14:22.385Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DjqKp5XS_-1WWN4X56sb-Q.png" /></figure><p><strong>Figure 1</strong>: A navigation map for strategic distillation [1]</p><h3>Strategic Distillation</h3><p>When developing systems with complex domains, how do we tackle the central problem without being distracted by secondary issues? A layered architecture helps by separating domain concepts from technical logic, but in a large system even the isolated domain layer may be unmanageably complex.</p><p>One of the essential lessons to be learned from Domain-Driven Design (DDD) is defining and focusing on the core domain. This process is known as distillation. Distilling means separating the components of a mixture in order to extract its essence. In software design, this translates to the partitioning of a larger system to make the core domain clearly visible and distinct. In DDD, distillation is part of strategic design, which deals with the modularization of large software systems.</p><p>Strategic distillation does many things. It directs efforts to the vital parts of the domain; it makes the overview of the system clearer; it facilitates communication by identifying a core model of reduced size; it guides refactoring; and it guides outsourcing, use of off-the-shelf components and decisions about assignments. Multiple patterns assist in the achievement of these goals.</p><h3><strong>Core Domain</strong></h3><p>The core domain is what makes the company make money — it is its competitive advantage. It’s what differentiates the application from the others, and what brings the most value to the users. Therefore, it is in the core domain that the focus should be. It should be crystal clear what is in the core domain and what is not. That will make the core domain — the real business asset — easier to understand and to change, which is everything the business wants. Because not all parts of the design will be equally refined, it is the definition of the core domain that should drive the priorities. When deciding where to refactor, the first place to consider should be the core domain.</p><p>Oftentimes, highly skilled developers gravitate to technical problems and lack domain knowledge. In such cases, the core will be developed by less skilled engineers, generally leading to a poor design or implementation of the main part of the system. This will likely create software that never does anything compelling for the users, no matter how well the technical infrastructure works or how nice the supporting features are.</p><p>Development in the core domain requires long-term commitment from the most skilled engineers. They must continuously learn about the business and acquire domain knowledge from the subject-matter experts, and apply their design skills to create the conceptual power in the model that will produce really useful and valuable software for users.</p><h3><strong>Generic Subdomains</strong></h3><p>There will be parts of the domain that are not core but that are still complex. Without an explicit distinction, these supporting complexities will make the core domain harder to understand.</p><p>Generic subdomains are subdomains that are not the motivation for the project. In order to make the core domain simpler, we should create generic models of these subdomains and place them in separate modules, leaving no trace of our specialties in them.</p><p>Identifying a generic subdomain gives us some options regarding the development of this subdomain:</p><ul><li><strong>Off-the-shelf solution</strong>: Because it is not part of our core domain, we can choose to buy an implementation or use open-source software. This leaves us with less code to develop and maintain, and a solution that is more mature and already used in multiple places. On the other hand, we still need to spend time evaluating it before deciding to use it, and integrating with it if we choose to use it.</li><li><strong>Published design or model</strong>: A published design or model will also be more mature than a brand new solution, and will already come with documentation to assist us in its use. We just have to make sure it meets our needs and is not overengineered for them.</li><li><strong>Outsourced implementation</strong>: Another option is to outsource the implementation of this subdomain. This choice will free the core team to work on the core domain, while also allowing more development to be done without increasing the size of the team and without dissipating core domain knowledge. Still, it will require time from the core team to design the interface and communicate their needs. In addition, this option will also generate the overhead of transferring ownership back inside, to understand the implemented code — which is still less overhead than in the case of specialized subdomains, which would require special background to understand.</li><li><strong>In-house implementation</strong>: Finally, a homemade solution will provide just what we want and nothing more, as well as easy integration with the rest of the system. The cost will be, of course, the internal development and maintenance time for these modules.</li></ul><h3><strong>Domain Vision Statement</strong></h3><p>There is a need to explain the value of the system concisely, be it at the beginning of the project, when a model does not yet exist, be it in the middle, for the sake of brevity. Besides that, the core domain may span multiple bounded contexts, in which different models with different concepts and rules apply. [2] Thus, these distinct models cannot be joined to show the goals they share.</p><p>The purpose of the domain vision statement is to describe the value of the core domain model. It should be short (about one page) and focused only on what differentiates that domain model from the rest. It can be used to guide resource allocation, to guide modeling choices, and to educate team members.</p><h3><strong>Highlighted Core</strong></h3><p>Since the domain vision statement has to be brief, it only identifies the core model in broad terms, and thus is too vague to identify core model elements. However, it is important that everyone in the project knows what is part of the core domain and what is not. The best way of achieving that is through the structure of the code, separating core from non-core elements logically or even physically. But it’s hard to arrive at the correct code structure before even having a view of how it should look like in the first place.</p><p>As options to meet that need, there are two main techniques for highlighting the core domain:</p><ul><li><strong>The Distillation Document</strong>: This document consists of a few pages explaining the core domain and the primary interactions between its elements. It can be a set of diagrams containing the most essential conceptual objects. It can be a list of those objects. It can simply be textual descriptions of them and their relationships. As with any document, it may end up not being maintained or read. The best way of preventing such problems is to avoid details and focus on the central abstractions, which tend to be more stable. If changes to the code require changing the distillation document, then we know those changes are important and require more review, and we know we have to communicate the team about the new version of the document.</li><li><strong>The Flagged Core</strong>: This is another form of highlighted core, in which we flag each core domain element within the primary repository of the model. It can be a UML stereotype identifying the core elements. It can be a set of Javadoc comments, if the team uses the code as the sole repository of the model. The important thing is that the core domain is clearly visible to the team.</li></ul><h3><strong>Cohesive Mechanisms</strong></h3><p>Sometimes there is the necessity of implementing a complex algorithm in order to solve a problem in the domain. However, mixing it up with the design of the domain may end up obfuscating the expressiveness of the domain model.</p><p>A possible way of dealing with that challenge is separating that kind of cohesive mechanism into a framework responsible solely for processing the technical computations, without any knowledge of the domain. The domain then expresses the “what” through an intention-revealing interface and delegates the “how” to the framework. Doing that will avoid coupling the model to a particular solution, which would limit future options. An example of cohesive mechanism is graph manipulation.</p><h3><strong>Segregated Core</strong></h3><p>Separating generic subdomains from the core subdomains helps to simplify the core domain. However, it’s not an easy task to identify all the generic subdomains and create models for them.</p><p>Segregating the core is basically attempting to do the same thing, but the other way around. Instead of worrying too much about the models of the subdomains that are not the motivation for the project, the segregation of the core focuses on the cohesion of the core domain, without immediately caring that much about defining and modeling the supporting subdomains, which is not irrelevant, but also not as important. The idea is to identify core subdomains and move them to new modules, leaving behind elements unrelated to the concept.</p><p>While this technique may make non-core parts of the system harder to work on, that cost is outweighed by the benefit of clarifying the core domain, since that’s where the most value will be added to the business.</p><h3><strong>Conclusion</strong></h3><p>The core domain is the most important thing to the business and to the users. The distillation techniques described here aim either to clarify or to unburden the core domain, thus giving traction to the business. Learning about them, therefore, gives us the opportunity to create differentiated and remarkable software that draws the attention of users and stands out from the competition.</p><h3><strong>References</strong></h3><ol><li>Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software.</li><li><a href="https://rafaelritter.medium.com/ddd-model-integrity-patterns-36d0e8ac9561">https://rafaelritter.medium.com/ddd-model-integrity-patterns-36d0e8ac9561</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a35e08ec9392" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DDD Model Integrity Patterns]]></title>
            <link>https://rafaelritter.medium.com/ddd-model-integrity-patterns-36d0e8ac9561?source=rss-9a1a8ffdb99e------2</link>
            <guid isPermaLink="false">https://medium.com/p/36d0e8ac9561</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[bounded-context]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <category><![CDATA[software-design]]></category>
            <dc:creator><![CDATA[Rafael Ritter]]></dc:creator>
            <pubDate>Wed, 10 Mar 2021 02:43:10 GMT</pubDate>
            <atom:updated>2021-03-10T10:39:26.427Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*Lv7xSHI-MqjB9xhF61stvg.png" /></figure><p><strong>Figure 1</strong>: A navigation map for model integrity patterns [1]</p><h3><strong>Strategic Design</strong></h3><p>Domain-Driven Design (DDD) tackles software complexity at different levels. Strategic design is the subset of DDD that operates at a higher level. Its main goal is to help dealing with large models, and its challenge is to achieve modularity without compromising the benefits of integrating different business operations. Because in large systems such design decisions must be negotiated between teams, strategic design does not take into account only technical considerations, but it often becomes the intersection between design and politics.</p><p>Defining explicit context boundaries is not only one of the essential aspects of DDD, but also, along with core domain distillation and large-scale structures, one of the keystones of strategic design. While it is theoretically possible to have a single, consistent model for the whole enterprise, this approach is rather complex and generally impractical. Therefore, letting each team develop its own models and explicitly limiting their applicability is the viable way to go. This pattern is commonly known as bounded context.</p><h3>Bounded Context</h3><p>A bounded context sets explicit boundaries in terms of team organization, code base, database schema and so on. In different contexts, different concepts, rules and terminology may be used. This helps in reducing cognitive load and avoiding confusion when shifting attention from one context to another. Furthermore, the correct split of the enterprise system in bounded contexts is fundamental to maintaining model integrity. A bad split of contexts, mixing up elements of distinct models, may cause two kinds of problems:</p><ul><li><strong>Duplication of concepts</strong>: When there are two model elements (and corresponding implementations) that represent the same concept.</li><li><strong>False cognates</strong>: When two people use the same term (or implemented object) thinking they are talking about the same thing, but they are not.</li></ul><p>Even though bounded contexts do contribute to modularity, this pattern differs from modules/packages. Objects from different bounded contexts will indeed be placed in different modules, but a single bounded context will also be composed of multiple modules, which will help organize the elements within that model.</p><h3><strong>Continuous Integration</strong></h3><p>Decoupling distinct models is necessary but not sufficient. Still there will be multiple people working in the same context, which might produce clashing understandings of the same model. In order to ensure consistency within a single context, applying the well-known process of continuous integration can be of great help. Domain-driven continuous integration implies not only an integration of the implementation, using an automated merge/build/test pipeline, but also an integration of model concepts. Concepts can be integrated by the constant exercise of the ubiquitous language in discussions between team members about the model and the application.</p><h3><strong>Context Map</strong></h3><p>Maintaining integrity within a single model is also very important, but still not enough. Everyone in the project has to be aware of other contexts as well, and relationships between contexts must also be clear to everyone. That’s where the context map comes into play. The context map identifies every model in the project and defines their bounded contexts, naming each of them and making their names part of the ubiquitous language. The point of the context map is not to envision the ideal scenario, but to map the current situation of the project. Once you can see the actual situation, changes and improvements in the state of affairs will become clearer.</p><p>The context map can take many forms. It can be a diagram, a textual description or even a discussion between the team. The important thing is that it is shared and understood clearly by everyone.</p><h3><strong>Relationships between Bounded Contexts</strong></h3><p>Several patterns describe the relationships between bounded contexts and their models. Which one to use depends heavily on the situation and the needs present. Here is a list of some of the most relevant among these patterns:</p><ul><li><strong>Shared Kernel</strong>: When two teams agree to share part of the domain model, along with the corresponding design and code. The benefit of this approach is reducing duplication and facilitating the integration between the two subsystems, but the price to pay is increased coupling, because the shared kernel cannot be changed so freely, since such changes affects both teams and have to be discussed and decided together.</li><li><strong>Customer/Supplier Development Teams</strong>: This is the relationship between an upstream and a downstream subsystem (the downstream system depends on the upstream). These subsystems naturally make up two distinct bounded contexts. Because it is a customer/supplier relationship, the needs of the downstream should be negotiated with the upstream, and it should be explicit which tasks will be prioritized and which will be deferred, so that the expectations of what will be delivered during the iteration process are aligned.</li><li><strong>Conformist</strong>: In this relationship, the downstream adopts the model and the ubiquitous language of the upstream team. Similar to sharing a kernel, the benefit of conforming is facilitating integration by eliminating the complexity of translation between bounded contexts, but the drawback is again increased coupling, since the dependency on the upstream is deepened and the downstream system is limited to the capabilities of the upstream model.</li><li><strong>Anticorruption Layer</strong>: The goal of the anticorruption layer is to avoid corrupting the model of the downstream system when it needs to integrate with an upstream system that has a different model, usually a legacy system or a system with a complicated and messy interface. The idea is to create a layer whose responsibility is to translate from one model to another, providing clients with an interface in terms of their own domain model. That interface can be implemented as a set of services. Internally, one way of implementing the anticorruption layer is by combining a set of façades, adapters and translators.</li><li><strong>Separate Ways</strong>: Sometimes the value of an integration is overestimated and its cost is underestimated. Going separate ways is a possibility that should be seriously considered in such cases. This pattern simply defines a bounded context that is completely decoupled from the rest.</li><li><strong>Open Host Service</strong>: This pattern defines a protocol that gives access to the system in question as a set of services and opens it so that all who need to integrate with it can use it. Open host services can be implemented as microservices or Service-Oriented Architecture (SOA) services. In fact, the motivation behind this pattern is the same behind SOA’s preference for intrinsic interoperability over custom integration: [2] simplifying communication between subsystems and avoiding integration complexity. The adoption of the open host service pattern implies that some part of the model will be shared: the service interface. As a result, downstream systems become coupled to the model of the open host, and downstream teams are forced to learn the language used by the host team.</li><li><strong>Published Language</strong>: This one is essentially a shared domain model in the form of a language definition. One of the problems that this pattern solves is the exchange of information between businesses, which are unlikely to adopt each other’s model. By publishing a language, a world of possibilities opens up for software development. The published language allows for the creation of generic tools that interoperate with multiple systems, instead of working only with a single one. If you wish to make use of such tools, just write your data according to the published language format. An example of published language is Portable Game Notation (PGN). [3] PGN is a published language for recording chess games. Chess games in PGN format are produced and consumed by most chess software. As with some other relationships, this pattern also simplifies integration and interoperability between systems.</li></ul><h3><strong>Conclusion</strong></h3><p>Maintaining model integrity is no easy task. Several patterns from DDD aim to achieve this goal, which is one of the main goals of strategic design. Whether it is maintaining integrity within a single bounded context through the application of continuous integration or between different contexts by explicitly limiting their applicability and establishing their relationships, these patterns and techniques help a great deal in keeping models pure, and therefore potent. Thus, take them into account when dealing with large models and systems. You are most likely already applying some of them. Understanding them and mapping them explicitly will certainly help you make better choices regarding your software and improve it continuously.</p><h3><strong>References</strong></h3><ol><li>Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software.</li><li><a href="http://www.soa-manifesto.org/">http://www.soa-manifesto.org</a></li><li><a href="https://en.wikipedia.org/wiki/Portable_Game_Notation">https://en.wikipedia.org/wiki/Portable_Game_Notation</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=36d0e8ac9561" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Trade-offs and Software Engineering]]></title>
            <link>https://rafaelritter.medium.com/trade-offs-and-software-engineering-22a41f838d9e?source=rss-9a1a8ffdb99e------2</link>
            <guid isPermaLink="false">https://medium.com/p/22a41f838d9e</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[trade-off]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Rafael Ritter]]></dc:creator>
            <pubDate>Mon, 06 Jul 2020 10:30:51 GMT</pubDate>
            <atom:updated>2020-07-06T16:07:27.758Z</atom:updated>
            <content:encoded><![CDATA[<p>According to the <a href="https://www.lexico.com/en/definition/trade-off">dictionary</a>, trade-off is “A balance achieved between two desirable but incompatible features; a compromise.” Put in other words, it means we must sacrifice something in order to gain something else. Trade-offs are limitations imposed by reality — they are reality saying to us: “You can’t have your cake and eat it too! You have to make a choice!”</p><p>Trade-offs are present in a wide variety of disciplines. One of the fields in which trade-offs are most applied is economics. In economic science, trade-offs are often expressed in terms of <a href="https://www.lexico.com/definition/opportunity_cost">opportunity cost</a>, which is the “The loss of other alternatives when one alternative is chosen.” To take an economic example, consider the decision to invest in stocks, which are risky but have higher potential returns, versus bonds, which are safe but have lower potential returns. Choosing one over the other means trading off between certainty and possible profits. In medicine, an example is the <a href="https://en.wikipedia.org/wiki/Patient_trade-off">patient trade-off</a>, in which patients need to weigh the possibility of a prolonged life expectancy against possible stressful or unpleasant treatment side-effects. Even board games involve trade-offs. In chess, for example, there is a concept called <a href="https://en.wikipedia.org/wiki/Sacrifice_(chess)">sacrifice</a>, in which a player gives up a piece with the goal of gaining some benefit in terms of strategy — essentially trading material for positional advantage. The list goes on and on.</p><p>Even when we leave the formal fields of study, and enter the realm of personal life, trade-offs are still there. Everything in life involves trade-offs — we simply cannot escape them, they rule life altogether. This stems from the fact that there are limits to our time and energy. If you are spending 5 hours per week hanging out with your friends, that’s 5 hours you could have spent exercising, or 5 hours you could have been working in your business. By choosing to do one thing, you are choosing to take away from another. Essentially, every choice has a cost — and if we want to make better choices, we must be aware of the options we have on the table as well as the trade-offs between them.</p><p>You might be wondering what all of this has to do with software. Well, quite a lot, actually. Just like the other disciplines, computer science has its own examples as well. The <a href="https://en.wikipedia.org/wiki/Space%E2%80%93time_tradeoff">space–time trade-off</a> shows that a program can often run faster if it uses more memory (e.g., by using lookup tables, memoization, caching, etc.). The <a href="https://en.wikipedia.org/wiki/CAP_theorem">CAP theorem</a> states that there is a trade-off between consistency and availability in every distributed data store when a network partition happens. And these are just some well-known, named examples. It certainly does not end here.</p><p>In software engineering, just as in life, trade-offs are omnipresent. They manifest from the micro to the macro level. As software engineers and architects, we will have to choose between different options for data types, data structures, algorithms, libraries, frameworks, languages, technologies, servers, databases, messaging systems, patterns, models, designs, architectures, etc. Oftentimes we are trading off “<a href="https://en.wikipedia.org/wiki/Non-functional_requirement">ilities</a>”, such as extensibility and maintainability. There is a trade-off even when choosing whether or not to write a test — some testing levels are inherently more expensive, slower, and more brittle than others, so we shouldn’t be writing all of them equally — we should have a <a href="https://martinfowler.com/bliki/TestPyramid.html">test pyramid</a>.</p><p>Precisely because of all this, we engineers must be very conscious. The fact that there are trade-offs does not imply that we are taking them into account; and the fact that we are not taking them into account does not imply that they cease to exist. As software engineers and architects, we are responsible for knowing, understanding, and considering trade-offs in order to make well-thought-out and informed decisions. If we want to be professionals, we need to take into consideration the advantages and disadvantages of each alternative before making a decision — otherwise, that decision becomes short-sighted. Therefore, the degree to which we think about, evaluate and analyze trade-offs in software systems is the degree to which we become increasingly better software professionals.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=22a41f838d9e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Domain-Driven Design]]></title>
            <link>https://rafaelritter.medium.com/domain-driven-design-8d0649366bca?source=rss-9a1a8ffdb99e------2</link>
            <guid isPermaLink="false">https://medium.com/p/8d0649366bca</guid>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <dc:creator><![CDATA[Rafael Ritter]]></dc:creator>
            <pubDate>Tue, 28 Aug 2018 17:00:26 GMT</pubDate>
            <atom:updated>2018-08-28T17:00:26.063Z</atom:updated>
            <content:encoded><![CDATA[<p>Domain-Driven Design, also known as DDD, is an approach to software development that separates the whole big project unity into smaller and simpler projects, each representing a distinct domain — “domain” being the particular field of knowledge for which the software is being built. By extension, it also tends to separate the general development team into smaller teams, each working on the respective domain for which it is responsible. To better understand the concept of Domain-Driven Design, first we need to ask why we should apply it instead of any different software development approach.</p><p>Suppose DDD is not being applied, and the project in which we are working can in fact be divided into more than one subset of domains. In this case, we are seeing the system that we are creating as a big picture instead of seeing it in terms of its more specific and focused parts; thus making the whole software development process a lot more complex and difficult, since we are not only ignoring the specializations that could have been made in order to facilitate the implementation, but, fundamentally, we are throwing away the so useful principle of “divide and conquer”.</p><p>For example, if we were to build an online shopping system, and our client also wanted to keep track of some reports such as best sale item, best sale month and so on, we could divide the general project into two: one for dealing with these reports, and another one to deal with the operations of purchasing and selling themselves. Not only that, but we could also — if we wanted to — create a third division: a subset of the online shopping system that deals only with login, logout and registering new users.</p><p>It is easy to see that this sort of separation creates the necessity for some kind of integration. Not coincidentally, Domain-Driven Design recommends the application of continuous integration in the development process. That aspect of DDD is fundamental in maintaining coherence between the multiple modules that are being implemented and that represent each distinct domain.</p><p>Besides its many strengths, DDD is not necessarily to be used every time and in every circumstance. Like all other software development approaches, the need for its use depends enormously on the situation that is being dealt with. Its value and potential, however, should not be diminished — as it was demonstrated in this very article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8d0649366bca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kanban]]></title>
            <link>https://rafaelritter.medium.com/kanban-af925da6fd24?source=rss-9a1a8ffdb99e------2</link>
            <guid isPermaLink="false">https://medium.com/p/af925da6fd24</guid>
            <category><![CDATA[management]]></category>
            <category><![CDATA[kanban]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Rafael Ritter]]></dc:creator>
            <pubDate>Wed, 15 Aug 2018 13:30:14 GMT</pubDate>
            <atom:updated>2018-08-15T13:30:14.462Z</atom:updated>
            <content:encoded><![CDATA[<p>Kanban is a project management methodology that aims at extracting maximum result from the development process, while being as precise as possible and avoiding waste. It is often (incorrectly) seen as just a board where cards are put. It is much more than that. Kanban is a set of principles, and it even has its own manifesto.</p><p>The <strong>Lean-Kanban Manifesto</strong> states which items are preferable over others, the first one being <strong>explicit conversations over intuitive abilities. </strong>This means that everyone must be clear in declaring what they want and expect, and no one should try to guess what has to be done. Developers will inevitably have questions, and in traditional methodologies it was thought that the registered requirements were everything that the developer needed — which is not true at all. That meant that meetings with the client were not planned ahead of time, which could delay the project’s schedule. If the developer has a question to the client, then he needs to ask it as soon as possible — otherwise, he will be idle, which is wasteful; and Kanban focuses on avoiding wastefulness.</p><p>Another main point of the manifesto is <strong>small steps over big changes.</strong> When we have small tasks that we can visualize in the process, we can literally see the workflow and the process in progress, and that’s very encouraging, because we explicitly follow the team’s advance. Another positive aspect of doing smaller and more basic tasks instead of giant ones is, again, not falling for the trap of traditional methodologies such as the cascade model. In cascade, the process of gathering and writing down requirements had to be done in the very beginning, and the development could not start until they were done. That process could take months. But the main problem of that approach is that the beginning of the project is the moment when we know the LEAST about the software being built. The requirements will probably be in constant change and improvement, the scope may change, and so on.</p><p><strong>Quality systems over heroic individuals </strong>is also a fundamental principle of the manifesto. In Kanban, we should not have only one single person doing everything or most of the work. Everyone should be participating and collaborating with the project, and there should be an environment as well as structures and tools that provides the quality that makes that possible. What is called “hero” is the person that often delays the project more than he/she helps it, because that person creates dependency and, obviously, is not always there all the time — thus he/she should not be the only one who knows and understands most if not all of the code.</p><p>Last but not least we have <strong>principles that guide our understanding over practices in which we must trust. </strong>And that defines what Kanban fundamentally is, which is a set of principles. Besides having tools, such as a board where we can visualize the workflow in progress (which is very important), Kanban is about people. In Kanban, all the workflow information is available for everyone, therefore everyone is well informed about the progress of the project. Kanban allows for a full view of the project situation and development, and thus for a better division of the tasks and collaboration of the team members, as well as a good access to important metrics about everything that is being done, about who is doing it, and how much time it is taking.</p><p>All of this makes Kanban reach its essential goal, which is, as we stated in the beginning, avoiding waste while providing quality. And Kanban does that very well.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af925da6fd24" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Manifesto Ágil]]></title>
            <link>https://rafaelritter.medium.com/manifesto-%C3%A1gil-e4a241905f6f?source=rss-9a1a8ffdb99e------2</link>
            <guid isPermaLink="false">https://medium.com/p/e4a241905f6f</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Rafael Ritter]]></dc:creator>
            <pubDate>Tue, 14 Aug 2018 12:18:03 GMT</pubDate>
            <atom:updated>2018-08-14T12:20:29.548Z</atom:updated>
            <content:encoded><![CDATA[<p>O Manifesto Ágil é a declaração dos princípios que constituem o desenvolvimento ágil de software. Em Engenharia de Software, o conjunto desses princípios é uma proposta de processo de desenvolvimento cujos objetivos são qualidade e velocidade na entrega de produtos de software, garantindo assim a satisfação do cliente.</p><p>O manifesto destaca <strong>4 itens principais</strong>, e em cada um deles faz uma comparação entre duas questões indicando qual é preferível de acordo com as metodologias ágeis. O primeiro desses quatro itens é <strong>o foco mais em indivíduos e interações do que em processos e ferramentas. </strong>De nada adianta o projeto ser desenvolvido sob os melhores processos e com as ferramentas mais modernas, se o produto sendo criado não condiz com aquilo que o cliente espera e deseja. Por isso, é fundamental a comunicação tanto entre a própria equipe quanto com o cliente, para que seja obtido o seu feedback e a sua validação daquilo que está sendo produzido — se condiz com o que ele espera — , e para que todos envolvidos no processo estejam a par desse tipo de informação. Além disso, a falta de feedback do cliente leva a desperdício de tempo e esforço, uma vez que caso o produto sendo criado não seja o produto correto, todo o desenvolvimento realizado até o momento foi feito em vão e deverá ser descartado, e o processo de implementação reiniciado.</p><p>Outro ponto importante do Manifesto Ágil, e também atrelado com a questão do feedback, é <strong>a preferência por software em funcionamento em detrimento de uma documentação abrangente. </strong>Isso significa que meses e meses de esforço sendo despendido com documentação não gera valor ao cliente. O que gera valor ao cliente é entrega contínua e frequente de software de qualidade. Essa continuidade e frequência não só agrega valor ao usuário constante e incrementalmente, mas permite também que o feedback sobre o software seja constante e, portanto, que esse software esteja sempre em processo de melhoria e aprimoramento. Nesse contexto, o conceito de MVP (produto mínimo viável) é essencial. Assim que algum produto de valor possa ser entregue ao cliente, ele deve ser entregue — não importando se não se trata da versão final.</p><p><strong>A colaboração com o cliente, acima da negociação de contratos, </strong>é o terceiro item essencial do manifesto. O formalismo pode deixar o projeto muito preso e muito restrito a um escopo inicial, o que dá pouco espaço para o produto evoluir e satisfazer o consumidor. Desse modo, a liberdade para colaborar com o cliente está intimamente ligada com <strong>responder a mudanças mais do que seguir um plano,</strong> o último item do Manifesto Ágil, pois possibilita mais flexibilidade em relação a mudanças no escopo ao invés de restringir o projeto a um plano específico e imutável.</p><p>Assim, esses quatro pontos principais compõem o Manifesto Ágil e tendem, quando corretamente aplicados, a aprimorar o processo de desenvolvimento de software em relação aos aspectos de qualidade, rapidez e frequência na entrega de valor aos clientes.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e4a241905f6f" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>