Jekyll2021-12-27T22:39:45+00:00https://earezki.com/feed.xmlDev|JournalBlogging about interests.Full stack developers2021-02-21T04:49:46+00:002021-02-21T04:49:46+00:00https://earezki.com/full-stack-developers<p><img src="/assets/full-stack-developer.png" alt="Full stack developer" title="Full stack developer" /></p>
<p>Looking for the meaning of <strong>full stack developer</strong> on <a href="https://www.google.com/search?q=full+stack+developer"><strong>Google</strong></a>, yields a range of definitions. Some of which says, a full stack developer should knows all the back end languages or the front end languages. Others say, the requirements are back end and front end skills. But I agree more with the definition that says, a full stack developer is required to have knowledge about the full stack developement cycle and tools, hence, I suggest the following definition:</p>
<p>A full stack developer, is a software developer, capable of fullfilling his tasks on the different technology stacks that constitutes a software application.</p>
<p>Skills required from a full stack developer, but not limited to, includes:</p>
<ul>
<li>To be able to start a project from scratch, communicate with the business stake holders and gather required features.</li>
<li>Make plannings to the project, and manage it using a project management method such as <a href="https://en.wikipedia.org/wiki/Agile_software_development"><strong>Agile</strong></a>.</li>
<li>Provision the infrastructure that would host the application.</li>
<li>Configure and secure the network.</li>
<li>Develop the <strong>front end</strong> for the different required clients (Web, Mobile, Desktop, …)</li>
<li>Design the database’s data structure.</li>
<li>Develop the <strong>back end</strong> that serves the different <strong>front ends</strong></li>
<li>Maintenance of all the above.</li>
</ul>
<p>Mastering all of the above skills gives the developer the ability to design and develop an application from scratch.</p>
<p>In the real world, by nature, almost, every developer have to some degree knowledge of all of the above. Does it means that almost, all the developers are <strong>full stack</strong> ? well, it depends, because usually when a recruter asks if you’re <strong>full stack</strong>, they want to know if you can work with <strong>the backend</strong>, <strong>the frontend</strong> and <strong>the database</strong>, so, yes, every developer is <strong>full stack</strong>.</p>
<p>However, it’s very hard to build expertise in all the domains all at once (otherwise we wouldn’t need teams), so it’s hard to find <strong>full stack</strong> developers that have solid and in depth knowledge of all those domains.</p>
<p>Let’s not forget that developers are humains (It’s hard to believe giving our nature but it’s true none the less), thus, they have preferences, hence, they have more knowledge at a field compared to another.</p>
<p>So, the <strong>full stack</strong> seems like a valued business word used to get recruters and managers hyped.</p>
<p>So, it seems that the title <strong>full stack developer</strong> and the question <strong>are you full stack</strong> is meaningless, because by definition, all the developers have knowledge of the <strong>backend</strong>, <strong>frontend</strong> and the <strong>database</strong>, then, maybe we should start talking about the stack itself.</p>
<h3 id="summary"><strong>Summary:</strong></h3>
<p>Talk about your experience with the different aspects, like how you can use the database, design the tables, issue SQL queries, but how you’re unable to optimize the design or the queries, how you can design and develop a GUI, but not able to produce state of the art UX designs, and how you’re skills at architecting the backend is unmatched, give a real experiece, how the database administrator was able to optimise your first iteration of the database tables structure, and how a UX designer intervened in the project and how you were able to progress a task or resolve a complicated issue at work.</p>Technical debt2021-01-02T04:49:46+00:002021-01-02T04:49:46+00:00https://earezki.com/technical-debt<p><img src="/assets/technical-debt.png" alt="technical debt" title="technical debt" /></p>
<p>In an agile environment, during the <a href="https://en.wikipedia.org/wiki/Scrum_(software_development)">sprint planning</a>, prioritized tasks are defined, and unnecessary ones are deferred. tasks such as:</p>
<ul>
<li>Migrate to the new programming language version.</li>
<li>Refactor a legacy module.</li>
<li>Use abstractions to better separate the modules.</li>
<li>… etc</li>
</ul>
<p>These are considered <strong>"Technical tasks"</strong> and they're delaShipping first time codeyed and rescheduled sprint after another.</p>
<p>Usually, the business prioritize functional requirements that contributes to the evolution of the product.
Shipping first time codeShipping first time code
For this reason, technical tasks needs to be listed, keep track of them, and communicate them to the business, explaining that these tasks are like a debt, delaying them would increase the debt hence it would cost more interest to pay off that debt in the long run.</p>
<p>On a previous project, we had two boards, a business board with all the functional requirements, and a technical board managed by the developers that holds all the technical requirements to reduce the debt.</p>
<p><strong>Ward Cunningham</strong> was the one to first make the comparison between technical complexity and debt, he said:</p>
<blockquote>
<p>Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite… The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.</p>
</blockquote>
<p>— <strong>Ward Cunningham, 1992</strong></p>
<p>When writing a code, we express our understanding of the problem and the solution, as the project matures, we acquire new knowledge and understandings on the software. Technical debt is accumulated when we're not refactoring existing code to express current understandings.</p>
<p>This doesn't mean that we should lower the standards of the design and the code to go faster while adding new features, at the contrary, we should always thrive to develop to the best to our understandings at the time of making.</p>
<p>And we shouldn't forget to prioritize technical tasks, to make adjustments and refactor old code when new knowledge and understandings are acquired.</p>Microservices vs Monoliths2020-09-12T04:49:46+00:002020-09-12T04:49:46+00:00https://earezki.com/microservices-vs-monoliths<p>Microservices are an architectural style that splits a software to a collection of fine-grained services. Those services have to be:</p>
<ul>
<li>Loosely coupled with other services.</li>
<li>Independently testable.</li>
<li>Maintainable</li>
<li>Solely testable and deployable.</li>
</ul>
<p>Microservices could use lightweight protocols to communicate with each other.</p>
<p>Each service solves a different problem than the other, and could be developed with a different programming language, database technology, operating system and hardware.</p>
<p>Microservices architecture shines in deployment, it integrates well with the CI/CD process. Making a change to the software, requires testing and deploying a handful of services. Time to market is essential to many domains.</p>
<p>Another clear advantage and a win is scalability, in a microservices architecture you can pinpoint services under load, and they could be scaled/optimized independently of other services, which in itself optimizes cost and resource usage.</p>
<p>Software developement as an indistry is not yet governed, and we are embracing new technologies and architectures as long as they have proved a successful usage, and solves existing problems.</p>
<p>Microservices was initially promoted by big companies, the likes of Netflix, Amazon, Spotify, Uber …</p>
<p>A common thing for all those companies, is that they are big, many teams, many developers, many business units. Without a proper organization, communication and management would be difficult. Not to talk about time to market and the cost of new features.</p>
<p>Microservices architecture, proved to be successful for their use case, it allowed them to continue to be competitive, scale their organization, and attract talented developers.</p>
<p>With all of those successful stories, and the trend microservices attracted, many developers consider Microservices a standard rather than a solution. Trying to apply it anywhere and to everything.</p>
<p>Let revisite some of the promises microservices promised to solve, and let's discuss each one:</p>
<ol>
<li>Zero downtime independent deployment.</li>
<li>Higher degree of organizational autonomy and distribute responsibilities.</li>
<li>Scalability</li>
<li>Reusability (authentication, search, …)</li>
</ol>
<h1 id="1-zero-downtime-independent-deployment"><strong>1. Zero downtime independent deployment:</strong></h1>
<p>With Microservices architecture, you can build and start the application quickly, which allows you to iterate more rapidly, and is more container friendly, as the startup time is massively reduced. You can change the behaviour and only test the parts you've changed or even introduce a breaking change assuming you're using a strategy (versioning as an example). Deploying a microservice doesn't require shutting the whole application, only the part that needs to. the other services could keep running in isolation and fullfilling user requests.</p>
<p>Usually building a monolith has a lot of files and dependencies, and it takes a lot of time to build and start. Testing a monolith is another challenge, because you need to ensure that you don't break the rest of the application. Deploying a monolith in a traditional organization requires shutting all the services, and then deploy the new release, then restarting the application, which brings the whole application down for a couple of minutes (If you're lucky and everything went well).</p>
<p>Build time is important, but as long as we're building a few times a day in a CI/CD platform, it doesn't matter to most of us, what matters is the time the developers are waiting for the build in their local machines. However, as long as we're writing proper unit tests, we might not even need to start the application. More over, modern tools allow incremental build which drastically reduces build time.</p>
<p>Now a day, we have many strategies and tools that allows to deploy a monolith with zero downtime. One can use blue green deployment, canary deployment, rolling updates …</p>
<p>My opinion, is that it depends, is build time crucial to you ? Are you using a language where you can't have incremental builds ? How is your release cycle being organized and what is your target ? What is your deployment strategy ? …</p>
<h1 id="2-higher-degree-of-organizational-autonomy-and-distribute-responsibilities"><strong>2. Higher degree of organizational autonomy and distribute responsibilities.</strong></h1>
<p>Scaling the business would require delivering more features, quickly and effectively. You can't ask developers to work on weekends, but you can bring in more developers. As the team grows, its responsibilities increases, getting more and more applications to maintain and enhance. Communication is another difficulty with big teams.</p>
<p>In a microservices architecture, you can scale your teams, decrease its responsibilities, and facilitate communication. Each team is responsible for a set of applications. Giving each team the liberty to choose the technologies and the approach that fits best their challenges.</p>
<p>Usually, in a monolith architecture, the teams are scaled vertically, adding more and more people to the same team, or a team besides that do the same thing. This introduces management overhead, and requires more communication. Development and solution design becomes harder.</p>
<blockquote>
<p>Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.</p>
</blockquote>
<p>— <strong>Melvin E. Conway</strong></p>
<p>The organization in itself, shouldn't be structured in such a way that only one team is responsible for the whole application. There should be different business units each has as many developers as required, responsible for the development and the maintenance of a set of code that belongs to that team.</p>
<p>Scaling the organization, doesn't require a microservices architecture, or a monolithic one. The organization and the teams should be structured around specific domains, allowing to add new business units, and new teams without affecting existing structure.</p>
<h1 id="3-scalability"><strong>3. Scalability.</strong></h1>
<p>As explained at the start of the article, microservices allows scalibity with an effective cost and resource usage.</p>
<p>On the other hand, monoliths usually are running on bare metal, or beefy virtual machines. To scale a monolith, you need to scale all the modules, which comes at a cost, buying new servers, or paying for expensive VMs.</p>
<p>I always believe that any application should fulfill a quorum, but exceeding a threshold, increases servers management overhead, at this stage, I would prefer a balance between vertical and horizontal scalability.</p>
<p>At the time of writing, we can get up to 448 vCPUs and 24576 GiB of RAM on aws, so we have a lot of room for vertical scalability before hitting the limit and start to scale out.</p>
<p>In microservices architecture, each call to an external service requires at least a 20ms extra time. And it's limited by the network's bandwidth.</p>
<p>In monoliths however, every call, is an internal process communication, no network is involved and you're limited by the machine (CPU, memory and disk).</p>
<h1 id="4-reusability"><strong>4. Reusability.</strong></h1>
<p>Reusability is at the heart of a lot of paradigms, starting from <strong>Object Oriented Programming</strong> and <strong>Functional Programming</strong>. To be able to reuse code, components or software, is a must to move forward and not have to build everything, every time from scratch.</p>
<p>So we should try to maximise the amount of work we can reuse. But this is not trivial and doesn't come by default in any system requires proper planning and execution.</p>
<p>In a microservices architecture, it's more common to create a service around a functionality that other systems require. The services communicate using the network, so you get to create new reusable services that have their own life cycle, programming language, infrastructure …</p>
<p>Reusability in monoliths comes in the form of inter process communication. Either external libraries, or in house libraries. For this reason you have to use the same programming language or the same compiled code.</p>
<p>Having a clean, modular monolith, makes good use of reusability. We have many layers and techniques to avoid the temptation of using new services to promote reusability.</p>
<p>In the Java ecosystem, there are a lot of languages that ran on the JVM, so we can develop libraries in Scala, and use them in Java.</p>
<p>Many startups and small companies have understood that Microservices makes their management much harder. they're a lot of stories on the internet of companies migrating back to monoliths.</p>
<p><strong>Netflix</strong> and the likes are big companies, having their own set of management complexities that doesn't apply to everyone. They have matured CI/CD platforms, tools and experience.</p>
<p>Without proper understanding of this architecture, we usually see <strong>distributed monoliths</strong> , you can't develop new features without adapting other services, you can't deploy a service without deploying everything, you can't scale individual services…</p>
<p>Monitoring is another challenge in Microservices, you have to have the infrastructure that would allow to monitor every application, and correlate between them. In a monolithic architecture, you have to monitor a single application.</p>
<p>I have compiled a list of which we should experiment until we hit a limit, then go to the next step.</p>
<ol>
<li>Monolith</li>
<li>Modular monolith</li>
<li>Services as dependencies.</li>
<li>Microservices.</li>
<li>Serverless</li>
</ol>
<p><strong>Conclusion:</strong></p>
<p>Don't use Microservices unless you really have to.</p>Microservices are an architectural style that splits a software to a collection of fine-grained services. Those services have to be:Best Of: The Early History Of Smalltalk2020-04-13T04:49:46+00:002020-04-13T04:49:46+00:00https://earezki.com/the-early-history-of-smalltalk<blockquote>
<p>Smalltalk’s design–and existence–is due to the insight that everything we can describe can be represented by the recursive composition of a single kind of behavioral building block that hides its combination of state and process inside itself and can be dealt with only through the exchange of messages.</p>
</blockquote>
<p>— <strong>Alan C.Kay</strong></p>
<blockquote>
<p>each Smalltalk object is a recursion on the entire possibilities of the computer. Thus its semantics are a bit like having thousands and thousands of computer all hooked together by a very fast network.</p>
</blockquote>
<p>— <strong>Alan C.Kay</strong></p>
<blockquote>
<p>Though it has noble ancestors indeed, Smalltalk’s contribution is anew design paradigm–which I called object-oriented–for attacking large problems of the professional programmer, and making small ones possible for the novice user. Object-oriented design is a successful attempt to qualitatively improve the efficiency of modeling the ever more complex dynamic systems and user relationships made possible by the silicon explosion.</p>
</blockquote>
<p>— <strong>Alan C.Kay</strong></p>Smalltalk’s design–and existence–is due to the insight that everything we can describe can be represented by the recursive composition of a single kind of behavioral building block that hides its combination of state and process inside itself and can be dealt with only through the exchange of messages.React Hooks: UseReducer Generics Params In Typescript2020-04-02T04:49:46+00:002020-04-02T04:49:46+00:00https://earezki.com/react-hooks-usereducer-generics-params-in-typescript<p>The new React Hooks introduces a lot of functions to encourage the creation of function components.</p>
<p>One of those functions is the <code class="language-plaintext highlighter-rouge">useReducer</code>.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">useReducer</span><span class="o"><</span><span class="nx">R</span> <span class="kd">extends</span> <span class="nx">Reducer</span><span class="o"><</span><span class="kr">any</span><span class="p">,</span> <span class="kr">any</span><span class="o">>></span><span class="p">(</span>
<span class="nx">reducer</span><span class="p">:</span> <span class="nx">R</span><span class="p">,</span>
<span class="nx">initialState</span><span class="p">:</span> <span class="nx">ReducerState</span><span class="o"><</span><span class="nx">R</span><span class="o">></span>
<span class="p">):</span> <span class="p">[</span><span class="nx">ReducerState</span><span class="o"><</span><span class="nx">R</span><span class="o">></span><span class="p">,</span> <span class="nx">Dispatch</span><span class="o"><</span><span class="nx">ReducerAction</span><span class="o"><</span><span class="nx">R</span><span class="o">>></span><span class="p">];</span>
</code></pre></div></div>
<p>Out of the box, the editor can infer the type of the state when you pass the reduce function. However, when I’ve took the state declaration and put it in an external file, suddenly the editor can no longer infer the type, and my state was of type <code class="language-plaintext highlighter-rouge">any</code>.</p>
<p>The solution is simple, you can’t just pass the <code class="language-plaintext highlighter-rouge">state</code> and the <code class="language-plaintext highlighter-rouge">action</code> to the <code class="language-plaintext highlighter-rouge">useReducer</code> generic types, you need to pass a <code class="language-plaintext highlighter-rouge">React.Reducer</code>.</p>
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="p">[</span><span class="nx">state</span><span class="p">,</span> <span class="nx">dispatch</span><span class="p">]</span> <span class="o">=</span>
<span class="nx">React</span><span class="p">.</span><span class="nx">useReducer</span><span class="o"><</span><span class="nx">React</span><span class="p">.</span><span class="nx">Reducer</span><span class="o"><</span><span class="nx">IComponentState</span><span class="p">,</span> <span class="nx">IAction</span><span class="o">>></span><span class="p">(</span><span class="nx">reduceFunction</span><span class="p">,</span> <span class="nx">initialState</span><span class="p">);</span>
</code></pre></div></div>The new React Hooks introduces a lot of functions to encourage the creation of function components.Hexagonal Architecture2020-03-29T04:49:46+00:002020-03-29T04:49:46+00:00https://earezki.com/hexagonal-architecture<blockquote>
<p>The _ <strong><em>hexagonal architecture</em></strong> _, or _ <strong><em>ports and adapters architecture</em></strong> _, is an architectural pattern used in _ <strong><em>software design</em></strong> _. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation</p>
</blockquote>
<p>— <strong><a href="https://en.wikipedia.org/wiki/Event-driven_architecture">wikipedia</a></strong></p>
<p><img src="/assets/Hexagonal_Architecture.png" alt="Hexagonal Architecture" title="Hexagonal Architecture" /></p>
<h6 id="figure-1-example-of-hexagonal-architecture-wikipedia">Figure 1: Example of hexagonal architecture <a href="https://en.wikipedia.org/wiki/File:Hexagonal_Architecture.svg">Wikipedia</a></h6>
<p>In <a href="/assets/Hexagonal_Architecture.png">Figure 1</a>, we can see that we have adapters for each client.</p>
<p><strong>Hexagonal Architecture</strong> is different from the classical <strong>Layered Architecture</strong> , in <strong>Layered Architecture</strong> the dependencies goes downward, AKA, the <strong>Presentation</strong> (UI) depends on the <strong>Domain</strong> , and the <strong>Domain</strong> depends on the <strong>Infrastructure</strong> (Usually there is an <strong>Application</strong> layer but we'll skip it for the sake of simplicity). (<a href="/assets/layered_architecture.png">Figure 2</a>)</p>
<p><img src="/assets/layered_architecture.png" alt="Layered Architecture" title="Layered Architecture" /></p>
<h6 id="figure-2--layered-architecture">Figure 2 : Layered Architecture</h6>
<p>Now a days, many teams who says they are doing Layered Architecture, are in fact using a sort of Hexagonal Architecture, the reason is that almost every one is using a Framework for dependency injection. and as such, you wire the <strong>Repository</strong> ( <strong>Infrastructure Layer</strong> ) into the <strong>Service</strong> ( <strong>The Application/Domain Layer</strong> ), Hence, the Domain doesn't depends on the Infrastructure no more, we can change the database implementation without affecting the domain.
It doesn't mean that dependency injection frameworks implement Hexagonal Architecture, but they encourage into doing so.</p>
<p>As demonstrated in <a href="/assets/Hexagonal_Architecture.png">Figure 1</a>, in hexagonal architecture, there are inner, and outer layers, the inner layer is the domain, it's the heart of our business. The inner layer exposes interfaces ( <strong>Ports</strong> ) to the outer layer.
The outer layer have the power to wire how the data is coming into our system (Gui, Restful api, SOAP, RMI, …), it controls where the data goes (Memory, a database, a messaging system, …). It does so by providing implementation to the interfaces ( <strong>Adapters</strong> ).</p>
<p>When using the hexagonal architecture, we should develop per domain use cases and not the supported clients. Afterward the clients would implements their adapters to adapt into our system.</p>
<p>I'm presenting this architecture because it integrates naturally with <a href="/domain-driven-design-core-concepts/">Domain Driven Design</a>.</p>
<p>In <a href="/assets/Hexagonal_Architecture.png">Figure 1</a>, we have a <strong>port</strong> for the persistence, we can have an <strong>adapter Repository</strong> to persist our <strong>Domain Models</strong> in a relational database, or in an object store, a flat file, S3, in memory, …. Also, <strong>Domain Events</strong> could be sent in memory or in a AMQP broker.
The advantage of <strong>Hexagonal Architecture</strong> is that we can have simple implementation for our <strong>ports</strong> to facilitate testing, and delay the decision making for the technologies behind the <strong>adapters</strong>.</p>The _ hexagonal architecture _, or _ ports and adapters architecture _, is an architectural pattern used in _ software design _. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automationAnemic vs Rich Domain Models2020-03-24T04:49:46+00:002020-03-24T04:49:46+00:00https://earezki.com/anemic-vs-rich-domain-models<p><img src="/assets/anemic_domain_model.jpg" alt="technical debt" title="technical debt" /></p>
<p>An <strong>Anemic Domain Model</strong> is a model that is focused on the state of the object. This is not what is advised while using <a href="/domain-driven-design-core-concepts/"><strong>Domain Driven Design</strong></a> ( <strong>DDD</strong> ) to develop a software.
Usually, it's a <a href="/tell-dont-ask-getters-are-evil/">bag of getters and setters with logic on top of services</a>.
There is nothing wrong with an <strong>Anemic Domain Model</strong> if what we're developing is a <strong>CRUD</strong> application.</p>
<blockquote>
<p>The basic symptom of an Anemic Domain Model is that at first blush it looks like the real thing. There are objects, many named after the nouns in the domain space, and these objects are connected with the rich relationships and structure that true domain models have. The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters. Indeed often these models come with design rules that say that you are not to put any domain logic in the the domain objects. Instead there are a set of service objects which capture all the domain logic, carrying out all the computation and updating the model objects with the results. These services live on top of the domain model and use the domain model for data.</p>
</blockquote>
<p>— <strong>Martin Fowler: <a href="https://www.martinfowler.com/bliki/AnemicDomainModel.html">Anemic Domain Model</a></strong></p>
<p>When using <strong>DDD</strong> , we aim to have <strong>Rich Domain Models</strong> which represents the behavior of the domain.</p>
<p>Strive for <strong>Rich Domain Models</strong>!</p>Domain Driven Design Core Concepts2020-03-23T04:49:46+00:002020-03-23T04:49:46+00:00https://earezki.com/domain-driven-design-core-concepts<p><img src="/assets/whiteboard.jpg" alt="" /></p>
<p>In this blog I'm sharing my understandings on the core concepts of Domain Driven Design.</p>
<p><strong>Domain Driven Design</strong> or <strong>DDD</strong> for short should only be used in fairly complex domain software. A <strong>CRUD</strong> application with little to no domain complexity doesn't justify the complexity of using <strong>DDD</strong>.</p>
<p><img src="/assets/DomainDrivenDesignReference.png" alt="" />Figure 1: Eric Evans Domain Driven Design overview</p>
<p><a href="/assets/DomainDrivenDesignReference.png">Figure 1</a> show an overview of DDD.</p>
<h3 id="core-elements-of-a-domain-model"><strong>Core elements of a Domain Model:</strong></h3>
<p><strong>Domain Driven Design</strong> requires extensive communication with a <strong>domain expert</strong> in order to understand the requirements and to discover <strong>sub-domains</strong>.</p>
<p>The software development team and the client, should speak the same language. To do so, while modeling the domain with the domain expert, we should extract the terminology used by the domain expert. The "software terms" should never be used while talking to a domain expert, terms such as <strong>class</strong> , <strong>cache</strong> , … may be interpreted differently which introduce confusion in both sides. Rule of thumb, ask as much questions as possible and don't be afraid to say I don't understand or to ask the same question again, better understand it now than to find out it's not what the client meant 2 months along the way.</p>
<blockquote>
<p>As software developers, we fail in two ways:
We build the thing wrong, or we build the wrong thing.</p>
</blockquote>
<p>— <strong>Steve Smith</strong></p>
<h3 id="sub-domains-and-bounded-contexts"><strong>Sub-Domains and Bounded Contexts:</strong></h3>
<p>A <strong>Domain Model</strong> is valid within a <strong>Bounded Context</strong> (BC for short), while modeling, we should be looking into which BC does that model belongs.</p>
<p>A model that is not clearly identified into which BC it belongs could be used in the wrong way/place, even if another model holds the same name (even if they refer to the same thing) and doesn't belong to the same BC, it's a totally different model.</p>
<p>Let's take a <strong>client</strong> model in a e-commerce website as an example, in the <strong>subscription</strong> bounded context, we only need the email, the name and the opt-in channels, however, in the <strong>billing</strong> bounded context, we require the name, billing info, credit card and the address.</p>
<p>One problem, would be if the client in the billing bounded context requires billing information validation, trying to reuse this same client model in the subscription would introduce inconsistency.</p>
<p>As such, we shouldn't try an reuse a model in a different bounded context where it doesn't belong.</p>
<blockquote>
<p>Explicitly define the context within which a model applies… Keep the model strictly consistent within these bounds, but don't be distracted or confused by issues outside_</p>
</blockquote>
<p>— <strong>Eric Evans</strong></p>
<p>In a perfect world, each bounded context should have distinct database, code base and team. so each bounded context is a separate application.
While this is great, but it's not easily applied in the real world, so we can keep separation using different modules, folders, projects …</p>
<p>Sub-domain and a Bounded Context are separate concepts, but are confusing to distinct from one another.</p>
<blockquote>
<p>Sub-domain is a problem space concept, Bounded context is a solution space concept.</p>
</blockquote>
<p>— <strong>Eric Evans</strong></p>
<p>Eric evans explains that the difference between the two as the difference between the floor and the carpet, the floor is the sub-domain (the problem space) while the carpet is the bounded context.
The carpet should fit well the floor, and there should be no hidden or visible parts that doesn't match.
And he goes explaining that a carpet that doesn't fit means that the domain changes.</p>
<p><strong>Context Maps</strong> allows to draw the boundaries where each bounded context ends.</p>
<h3 id="ubiquitous-language"><strong>Ubiquitous Language:</strong></h3>
<p>The Ubiquitous Language is a core concept of DDD, it's the language spoken by the software development teams that work in the same software domain, but not only, it's also the language spoken by the stakeholders. This allows to have fluid conversations without <strong>Translations</strong>.</p>
<p>The Ubiquitous Language should be used everywhere in the bounded context, in conversations, code, diagrams, boards, emails …</p>
<blockquote>
<p>A project faces serious problems when its language is fractured.</p>
</blockquote>
<p>— <strong>Eric Evans</strong></p>
<p>I've seen many times the stakeholders adapting to the language of the development teams because they are rigid and want to use their terminology, I've also seen demos where the team explains their technical solution rather than the solution itself. The result is the stakeholders don't understand what teams are presenting, and in the early stages, they may just assume that everything is well and that the team is advancing, while the reality is that the teams are working on the wrong thing.
Communication is key, there is no shame in saying I don't understand!</p>
<h3 id="summary"><strong>Summary:</strong></h3>
<p><strong>Problem Domain</strong> : The specific problem the software is trying to solve.
<strong>Core Domain</strong> : the customer's business.
<strong>Sub-Domains</strong> : Separate features/applications the software should support and interact with.
<strong>Bounded Context</strong> : A responsibility with explicit boundaries that separate it from other parts of the system.
<strong>Context Mapping</strong> : The process of identifying bounded contexts and their relationships to one another.
<strong>Shared Kernel</strong> : Part of the model that is shared by two or more teams, who agree not to change it without collaboration.
<strong>Ubiquitous Language</strong> : A language using terms from the domain model that programmers and domain experts use discuss the system.</p>Tell, Don’t Ask: Getters Are Evil2020-03-21T04:49:46+00:002020-03-21T04:49:46+00:00https://earezki.com/tell-dont-ask-getters-are-evil<p><img src="/assets/tell_dont_ask.jpg" alt="tell dont ask" title="tell dont ask" /></p>
<p>Many times we were told that getters are evil and we should stop using them.</p>
<p>So, What is wrong with getters ?</p>
<p>Well, it leaks abstraction and you expose the internal structure of your objects (which is not OOP). as a result you have your business logic scattered around and not centralized, next thing, you’ll have duplicated business logic which is not good at all as you might guess.</p>
<p>you might argue that you have a service (<code class="language-plaintext highlighter-rouge">ProductService</code>) that calculates the price of product and takes in charge of the business logic, if you do, then you need to expose the <code class="language-plaintext highlighter-rouge">price</code> with a <code class="language-plaintext highlighter-rouge">getPrice</code> for example, and you may be calling this <code class="language-plaintext highlighter-rouge">getPrice</code> on the view directly as it’s already a POJO, next thing you figure that you should convert it to the customer’s currency, and “BAM”, you (or another developer 🙂 ) implement this in the view because it’s so simple. and in many other cases you’ll find yourself calling <code class="language-plaintext highlighter-rouge">getPrice</code> on the product object and then you start implementing the expected behavior. but one of the developers will forget the tax, another will forget a promotion. etc. you get the idea.</p>
<p>You should also think about future developers, they’ll find it easier to grab the data and do the logic quickly instead of adding it to the Service and then injecting the service (Maybe there are many layers that need to be injected). This point means that you need to train new developers and especially juniors or hire only seniors (Yeah it’s costy). Or, you can opt for the simple solution. Better design your application and separate the persistence and the view model from the domain model.</p>
<p>But then, when do getters makes sense, and are mandatory, well, as long as they are used to expose information to other layers. Which means you can create your persistent model through getters in your domain model.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Product</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">cost</span><span class="o">;</span>
<span class="kt">double</span> <span class="nf">getCostFor</span><span class="o">(</span><span class="kt">int</span> <span class="n">quantity</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">cost</span> <span class="o">*</span> <span class="n">quantity</span><span class="o">;</span>
<span class="o">}</span>
<span class="kt">double</span> <span class="nf">getCost</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">cost</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>There is no problem with this as long as the <code class="language-plaintext highlighter-rouge">getCost()</code> is only used to create a DTO.</p>
<p>However, this is not the best idea.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Product</span> <span class="o">{</span>
<span class="nc">ProductDto</span> <span class="nf">toDto</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">ProductDto</span><span class="o">(</span><span class="n">cost</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>It says, the domain object knows about the DTO, which sounds like a fancy word for a getter. And it’s even worse, because a DTO should not have any logic. All the issues you want to avoid when you’re not using getters you can have when using DTO’s this way.</p>
<p>So, for now, I stick with the first approach to exchange data. Make sure to implement a method where It makes sense. If I used the <code class="language-plaintext highlighter-rouge">getCost()</code> to perform logic I’m 100% aware of It cause It makes sense In the context.</p>Speed Up Your Computations2017-09-11T04:49:46+00:002017-09-11T04:49:46+00:00https://earezki.com/speed-up-your-computations<p><img src="/assets/speed_up_your_computations.jpg" alt="Speed Up Your Computations" title="Speed Up Your Computations" /></p>
<p>Sometimes you find yourself trying to squeeze the last bits of your CPU to give you some more milliseconds. Or you may hate the smell of a melting CPU. Or maybe you are just a performance maniac. If you happen to be in one of these cases, keep reading this post.</p>
<p>So let us say you are designing a banking application in which you have a Transaction entity, and let us say that the entity contains these simple fields.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Transaction</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">TransactionId</span> <span class="n">id</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">Money</span> <span class="n">amount</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">AccountId</span> <span class="n">debit</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">AccountId</span> <span class="n">credit</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The Money would, simple holding only the value itself as:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Money</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kt">double</span> <span class="n">value</span><span class="o">;</span>
<span class="nc">Money</span> <span class="nf">add</span><span class="o">(</span><span class="nc">Money</span> <span class="n">other</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Money</span><span class="o">(</span><span class="n">value</span> <span class="o">+</span> <span class="n">other</span><span class="o">.</span><span class="na">value</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>And then you have an account with a liste of all the transactions that it has made.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Account</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">AccountId</span> <span class="n">id</span><span class="o">;</span>
<span class="o">...</span>
<span class="kd">private</span> <span class="nc">List</span><span class="o"><</span><span class="nc">Transaction</span><span class="o">></span> <span class="n">transactions</span><span class="o">;</span>
<span class="o">...</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Now you are tasked to calculate the total amount of those transactions. A simple functional solution with java 8 streams would be:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Account</span> <span class="o">{</span>
<span class="nc">Money</span> <span class="nf">total</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">transactions</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="nl">Transaction:</span><span class="o">:</span><span class="n">amount</span><span class="o">)</span>
<span class="o">.</span><span class="na">reduce</span><span class="o">(</span><span class="nc">Money</span><span class="o">.</span><span class="na">ZERO</span><span class="o">,</span> <span class="nl">Money:</span><span class="o">:</span><span class="n">add</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>You test it and it works. The next day, your colleagues start to complain about performance, and given there are millions of transactions, the profiler points to your method.</p>
<p>What are you going to do now? Hmm, let me see, yeah, I got it, parallelism to the rescue. You take this great idea to your colleagues and they turn you down because the server is already filled with active threads. Now what? Well, you just need to better use your cycles (bear the word).</p>
<p>Let’s change the structure of the Transaction entity.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Transactions</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">TransactionId</span><span class="o">[]</span> <span class="n">uuid</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">Moneys</span> <span class="n">amount</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">AccountId</span><span class="o">[]</span> <span class="n">debit</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">AccountId</span><span class="o">[]</span> <span class="n">credit</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">int</span> <span class="n">transactionsCount</span><span class="o">;</span>
<span class="nc">Money</span> <span class="nf">total</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">Money</span> <span class="n">result</span> <span class="o">=</span> <span class="nc">Money</span><span class="o">.</span><span class="na">ZERO</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Notice the name that is transactions (with an S), and also the entity holds arrays rather than single objects.</p>
<p>Now the Account will hold this new Transactions object instead of the Transaction list.</p>
<p>Then the calculation becomes:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Account</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">Transactions</span> <span class="n">transactions</span><span class="o">;</span>
<span class="nc">Money</span> <span class="nf">total</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">transactions</span><span class="o">.</span><span class="na">total</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Nothing wrong with this code, always OOP !</p>
<p>We also changed the Amount class, the new object (Amounts) hold an array of values (primitive double array).</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Moneys</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kt">double</span><span class="o">[]</span> <span class="n">values</span><span class="o">;</span>
<span class="nc">Money</span> <span class="nf">add</span><span class="o">(</span><span class="nc">Money</span> <span class="n">other</span><span class="o">)</span> <span class="o">{</span>
<span class="kt">double</span> <span class="n">result</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">values</span><span class="o">.</span><span class="na">length</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
<span class="n">result</span> <span class="o">+=</span> <span class="n">value</span><span class="o">[</span><span class="n">i</span><span class="o">];</span>
<span class="o">}</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Money</span><span class="o">(</span><span class="n">result</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>On my machine and after warming the JVM for a million rounds, this implementation is around 32X faster than the previous one (test the code for yourselves on <a href="https://github.com/earezki/speedup-computations">Github</a>) and share your results).</p>
<p>Now, why this is faster? It turns out that modern CPUs work better when all the calculation is applied on data that is packed together. The CPU reads data from the memory in cache lines (it is around 64KB in most CPUs) and stores it in the L1 cache. When the CPU wants to fetch data, it will compare its address to the address space in the L1 then L2 then L3 caches. If the address is not there, the CPU will read a whole cache line starting from the nearest alignment to the needed address and store it in the L1 cache (in this example, the CPU will load all the attributes of the Transaction to use the amount attribute).</p>
<p>The first example suffers a lot from cache miss, which means the CPU reads a lot of data that it doesn’t need, then throws it away, and then reads more data that it won’t need.</p>
<p>One more advantage is that this approach fits naturally with SIMD operations (Kinda hard to use in java anyway, but the compiler may chose to optimize the code to use it).</p>
<p>To a give an example, the read from the L1 cache in Intel i7 5500 takes around 4 cycles for simple access, whereas a read from main memory takes around 120 cycles.</p>
<p>Now you have it; most of the time, you probably won’t use it, this technique is heavily used in the game development industry, and in embedded systems.</p>
<p>And to make a disclaimer, you may not benefit from this approach in a large web app, because other scheduled threads will pollute the cache anyway, and your best bet is the large shared L3 cache (for Intel, at least).</p>