<?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 M Yauri M Attamimi on Medium]]></title>
        <description><![CDATA[Stories by M Yauri M Attamimi on Medium]]></description>
        <link>https://medium.com/@yauritux?source=rss-fa3ab82e4f38------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*MoWVt2pb-eE9N4KXCxXfFg.png</url>
            <title>Stories by M Yauri M Attamimi on Medium</title>
            <link>https://medium.com/@yauritux?source=rss-fa3ab82e4f38------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 18:18:02 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@yauritux/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[From Backend Engineer to AI Engineer]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://yauritux.medium.com/from-backend-engineer-to-ai-engineer-df20307f9b1e?source=rss-fa3ab82e4f38------2"><img src="https://cdn-images-1.medium.com/max/600/1*cHlNgTXaEhWmGnKxmJDa2Q.png" width="600"></a></p><p class="medium-feed-snippet">The Natural Evolution from Backend Engineering to Agentic AI, and Why Elixir is the Runtime You Didn&#x2019;t Know You Needed</p><p class="medium-feed-link"><a href="https://yauritux.medium.com/from-backend-engineer-to-ai-engineer-df20307f9b1e?source=rss-fa3ab82e4f38------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://yauritux.medium.com/from-backend-engineer-to-ai-engineer-df20307f9b1e?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/df20307f9b1e</guid>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Tue, 28 Jul 2026 11:49:38 GMT</pubDate>
            <atom:updated>2026-07-28T15:12:20.467Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[How I Personally Grasp the Essence of Concurrency in Go]]></title>
            <link>https://yauritux.medium.com/how-i-personally-grasp-the-essence-of-concurrency-in-go-eea64b541292?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/eea64b541292</guid>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Tue, 24 Mar 2026 00:38:17 GMT</pubDate>
            <atom:updated>2026-03-24T00:38:17.445Z</atom:updated>
            <content:encoded><![CDATA[<h3>Philosophy, Patterns &amp; The Power of Built-in Tools</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*lJrQ4A-mh3zv7RiO" /><figcaption><strong>The Go Factory:</strong> How Channels Move Data Safely</figcaption></figure><blockquote>Why Go says “Don’t communicate by sharing memory” and how to build robust systems without external libraries.</blockquote><p>If you come from a background in Java (like me), Python, or JavaScript, the word “concurrency” might trigger a slight sense of anxiety. We are taught that threads are dangerous, race conditions are lurking around every corner, and debugging deadlocks is a nightmare.</p><p>Then you meet Go.</p><p>Go doesn’t just offer a new way to write concurrent code; it offers a new way to <strong>think</strong> about it. But beyond the famous mantras, how does this philosophy translate to actual engineering ? And perhaps most importantly, <strong>do you need external libraries to make it work</strong> ?</p><p>The answer is a resounding <strong>NO</strong>. Everything you need to build enterprise-grade concurrent systems is built directly into the language and its standard library.</p><p>In this post, we’ll recap the core philosophies of Go concurrency, explore the patterns that make it powerful, and highlight the built-in tools that let you implement them without adding a single dependency.</p><h4>1. The Core Philosophy: CSP vs. Shared Memory</h4><p>The most famous quote in Go concurrency comes from Rob Pike:</p><blockquote><em>“Don’t communicate by sharing memory; share memory by communicating.”</em></blockquote><p>This is the principle of CSP (Communicating Sequential Processes). To understand it, we need to contrast it with the traditional model.</p><h4>The Traditional Model: Shared Memory</h4><p>Imagine a <strong>single-occupancy bathroom</strong> in an office or any public places.</p><ul><li><strong>The Resource:</strong> The bathroom (a <em>variable</em> in memory).</li><li><strong>The Problem:</strong> Multiple people (<em>threads</em>) need to use it.</li><li><strong>The Solution:</strong> A lock on the door (<em>mutex</em>). You must acquire the key, use the bathroom, and return (<em>release/unlock</em>) the key after you use it.</li><li><strong>The Risk:</strong> What if someone forgets to unlock the door ? (<em>Deadlock</em>). What if someone sneaks in without the key ? (<em>Race Condition</em>).</li></ul><h4>The Go Model: CSP</h4><p>Imagine a <strong>factory conveyor belt</strong> (a <em>Channel</em>).</p><ul><li><strong>The Resource:</strong> The parts being built (<em>data</em>).</li><li><strong>The Process:</strong> Worker A places a part on the belt. The belt moves it to Worker B.</li><li><strong>The Safety:</strong> At any specific moment, <strong>only one person is holding the part</strong>. When it is on the belt, no one is touching it.</li><li><strong>The Focus:</strong> You aren’t protecting a <em>static (shared) variable</em>; You are managing the <strong>flow of data</strong>.</li></ul><blockquote><strong>In Go:</strong> You don’t protect a variable with a lock! You pass the variable over a chan. Ownership is transferred safely from one goroutine to another.</blockquote><h4>2. The Engineering Mantra: Sequence and Backpressure</h4><p>There is a second, practical mantra that follows the philosophy:</p><blockquote>“Don’t over engineer things by using shared memory and complicated, error prone synchronization primitives; instead, use message-passing between Goroutines so variable and data can be used in the appropriate sequence.”</blockquote><p>This is where Go shines in production. Channels aren’t just for moving data; they are for <strong>controlling time</strong>.</p><h4>The Relay Race Analogy</h4><ul><li><strong>Shared Memory:</strong> Workers check a whiteboard every second to see if the previous step is done. (Busy waiting, complex logic)</li><li><strong>Channels:</strong> Workers stand in a line. Worker 2 physically cannot start until Worker 1 hands them the baton.</li></ul><p><strong>Why this matters:</strong></p><ol><li><strong>Sequence Guaranteed: </strong>A receive operation ( &lt;- ) blocks automatically until data arrives. You don’t need to write if done {...} loops.</li><li><strong>Natural Backpressure:</strong> If the Consumer is slow, the Channel fills up. The Producer automatically blocks and waits. This prevents your program from consuming all RAM trying to process data faster than the database can save it.</li></ol><h4>3. The Producer-Consumer Problem (Solved Simply)</h4><p>The classic <em>Producer-Consumer</em> pattern is kind of “Hello World” of concurrency. It solves the problem of balancing speed between data creation and data processing.</p><p>In many languages, implementing a <strong>bounded-buffer</strong> (a queue that stops accepting data when full) requires complex condition variables and locks.</p><p><strong>The Traditional Way (as conceptually handled in Java)</strong></p><pre>// Requires Mutex, Condition Variables, Wait(), Signal(), etc.<br>// Easy to get wrong. Hard to read.<br>void put(item) {<br>    lock.acquire();<br>    while (queue.isFull()) { condition.wait(); }<br>    queue.add(item);<br>    condition.signal();<br>    lock.release();<br>}</pre><p><strong>The “Go” Way</strong></p><p>In Go, a <strong>Buffered Channel</strong> is a <em>thread-safe</em> Producer-Consumer queue.</p><pre>// Create a buffer that holds exactly 5 items<br>buffer := make(chan int, 5)<br><br>// Producer<br>go func() {<br>    for i := 0; i &lt; 100; i++ {<br>        buffer &lt;- i // Automatically blocks if channel is full (Backpressure!)<br>    }<br>    close(buffer)<br>}()<br><br>// Consumer<br>go func() {<br>    for item := range buffer { // Automatically blocks if channel is empty<br>        process(item)<br>    }<br>}()</pre><p><strong>That’s it.</strong> No locks. No condition variables. No manual signaling. The language runtime handles the synchronization for you.</p><h4>4. The Go Standard Toolbox (No External Libraries Needed)</h4><p>One of Go’s greatest strengths is that you do not need third-party frameworks to handle different patterns of concurrency. The standard library is batteries-included.</p><pre>+---------------------+----------------+------------------+--------------+<br>|.  Pattern.          |. Tool.         | Package.         |.  Built-In ? | <br>+---------------------|----------------|------------------|--------------+<br>| Lightweight Threads | goroutine      | Language Keyword |  ✅ Yes      |<br>| Communication       | chan           | Language Keyword |  ✅ Yes      |<br>| State Protection    | sync.Mutex     | sync             |  ✅ Yes      |<br>| Wait Groups         | sync.WaitGroup | sync             |  ✅ Yes      |<br>| High Perf Counters  | atomic         | sync/atomic      |  ✅ Yes      |<br>| Lifecycle/Timeout   | context        | context          |  ✅ Yes      |</pre><p><strong>Structure Concurrency with</strong> context</p><p>In traditional concurrency, knowing when to stop a goroutine is hard. Go solves this with the context package. It allows you to cascade cancellation signals.</p><pre>ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)<br>defer cancel()<br><br>// Pass ctx to your goroutines. <br>// If the timeout hits, all listening goroutines stop gracefully.</pre><p>This prevents <strong>goroutine leaks</strong>, a common bug in other languages where background tasks keep running forever after a request finishes.</p><h4>5. When to Break the Rules</h4><p>While “Share memory by communicating” is the default path, Go is pragmatic. As an engineer we know that there’s “size fits for all”. It always depends on the usecase / problem we’re trying to solve. There are times when shared memory is better:</p><ol><li><strong>Simple State:</strong> If you just need to protect a simple config map or cache, a sync.Mutex is often clearer than setting up a channel loop.</li><li><strong>Performance:</strong> Channels have a small overhead. For extremely high-frequency counters, sync/atomic is faster.</li><li><strong>Internal State:</strong> If a struct has internal state that shouldn’t be exposed, protecting it with a mutex inside its methods is cleaner.</li></ol><blockquote><strong>The Rule of Thumb:<br></strong><em>- Use </em><strong><em>channels</em></strong><em> to orchestrate </em><strong><em>flow</em></strong><em> (pipelines, worker pools)<br>- Use </em><strong><em>mutexes</em></strong><em> to protect state (caches, configs)</em></blockquote><h4>6. Beyond the Basics: Actor Model &amp; Async</h4><p>Go’s model is unique compared to other ecosystems:</p><ul><li><strong>Vs. Async/Await (JS/Python):</strong> <strong>Go</strong> hides the complexity. You write code that <em>looks synchronous</em> (e.g., response:= http.Get(...)), but the runtime parks the goroutine efficiently. <strong>No callback hell</strong>, <strong>no explicit</strong> await keywords everywhere.</li><li><strong>Vs. Actor Model (Erlang/Elixir/Akka):</strong> <strong>Go</strong> is similar but more flexible. In <em>Actor Model</em> pattern: mailboxes (<em>channel</em> in Go) belong to actors. In <strong>Go</strong>, <em>channels</em> are independent entities that multiple goroutines can share. However, you can build an Actor in Go using a goroutine + switch statement + channel, but you aren’t forced into that paradigm.</li></ul><h4>Conclusion</h4><p>Concurrency in Go is not just about doing multiple things at once; its about <strong>composing</strong> those things safely.</p><p>By adopting the CSP philosophy, you shift your mindset from <strong>protecting resources</strong> (<em>locks</em>) to <strong>managing flow</strong> (<em>channels</em>). By leveraging the built-in tools like chan, context, and sync, you avoid the dependency hell common in other ecosystems.<br>You get:<br>1. <strong>Safety:</strong> Race conditions are harder to introduce.<br>2. <strong>Backpressure:</strong> Systems self-regulate under load.<br>3. <strong>Simplicity:</strong> Complex workflows look like simple pipeline.<br>So.. the next time you face a concurrency problem, remember the mantra: <strong>Don’t communicate by sharing memory. Share memory by communicating</strong>. And trust the tools that come right out of the box.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eea64b541292" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My Journey with Python (Part II)]]></title>
            <link>https://yauritux.medium.com/python-3-more-advanced-concepts-36b1094f32d6?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/36b1094f32d6</guid>
            <category><![CDATA[python3]]></category>
            <category><![CDATA[python-advanced]]></category>
            <category><![CDATA[python-decorators]]></category>
            <category><![CDATA[oop-in-python]]></category>
            <category><![CDATA[python-generators]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Sat, 25 May 2024 13:36:49 GMT</pubDate>
            <atom:updated>2025-01-01T17:05:36.789Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pwweuIi3xytYsF5jGUGUSQ.jpeg" /></figure><p>Finally after 5 years I got the chance to write again. This is the second part of my whole five-planned series as shown below:</p><ol><li><a href="https://blog.yauritux.link/my-journey-with-python-part-i-fdbc2609947c">Python 3 Introduction</a>.</li><li>Python 3 More Advanced Concepts → <em>you are here</em></li><li>Develop your First Micro-service <em>(coming soon)</em></li><li>Python for Data Enthusiast <em>(coming soon)</em></li><li>Utilizing Generative AI (LLM) for building an AI-based Application <em>(coming soon)</em></li></ol><h3>Python 3 More Advanced Concepts</h3><p>This part will comprise of these following sections:</p><ol><li>Object Oriented Programming (OOP) in Python</li><li>Decorator in Python</li><li>Python List Comprehension</li><li>Generators in Python</li><li>Context Manager</li><li>Asynchronous Programming</li><li>Lambda Function</li></ol><blockquote><strong>Caveats:</strong><br>This is going to be a very long article due to lots of topic that we’re going to cover within one post, hence I would suggest to read each section separately whenever you’re free or feels like to do it.</blockquote><p>Hope you’ll like it and let’s jump in !</p><h4>Object Oriented Programming (OOP) in Python</h4><p>I won’t go into the details about what OOP is since we can find it a lot from anywhere today . I would recommend to start by asking ourselves on why we need OOP at the first point, and subsequently start with the 4 basic principles of OOP such as : Encapsulation, Inheritance, Polymorphism, and Abstraction. One of the good one can be read from <a href="https://www.educative.io/blog/object-oriented-programming">educative.io/blog/object-oriented-programming</a>.</p><p><strong>&gt; Defining a Class in Python</strong></p><p>Once you got all the points and good reasons for OOP, let’s see how to implement it in Python3 by defining a standard class to represent the “CustomerAccount” in a Bank called “Bank-RUPT” below:</p><pre>class CustomerAccount:<br><br>  # disclaimer (this doesn&#39;t represent a real bank name)<br>  bank_name = &quot;Bank-RUPT&quot;<br><br>  def __init__(self, acc_no: str, acc_type: str, balance: float):<br>    self.acc_no = acc_no<br>    self.acc_type = acc_type<br>    self.balance = balance<br><br>  def withdraw(self, amt: float):<br>    if self.balance &lt; amt:<br>      raise Exception(&quot;Balance is not sufficient!&quot;)<br><br>    self.balance -= amt<br>    print(f&quot;{amt} is withdrawn from your account.&quot;)<br>    print(f&quot;Your balance now is {self.balance}&quot;)<br><br>  def deposit(self, amt: float):<br>    if amt &lt;= 0:<br>      raise Exception(&quot;Deposit amount should be greater than 0.00!&quot;)<br><br>    self.balance += amt<br>    print(f&quot;{amt} has been added into your account.&quot;)<br>    print(f&quot;Your balance now is {self.balance}&quot;)<br><br>  def current_balance(self):<br>    return self.balance<br><br>  def compare_customer_balance(cust1, cust2):<br>    if cust1.current_balance() &gt; cust2.current_balance():<br>      return cust1<br>    return cust2</pre><p><strong>Some notably points here:</strong></p><ol><li>We use keyword class to define a class named CustomerAccount, ended with colon ( : )</li><li>There are two types of fields / attributes can be defined within a Python <strong>class</strong> respectively as follow:<br>- <strong>Class Field</strong>, i.e. field that is attached into the <strong>class</strong> itself, hence any instance of the <strong>class</strong> will have the same value for it. In our sample for theCustomerAccount <strong>class</strong>, bank_name falls into this type. So, whenever you update the value of the bank_name, all instances / objects of the CustomerAccount <strong>class</strong> will always refer to the same value. This is the same concept as what we used to know in <strong>Java</strong> for static fields. <br>- <strong>Instance Field</strong>, i.e. <strong>field</strong> that is attached into the instance / object of the <strong>class</strong>. As you might guess, all fields / attributes belong to this type will have their own value (specific to each instance). So, you can guarantee that you can have different value for each instance of the class. In our sample for the CustomerAccount <strong>class</strong> … acc_no, acc_type, and balance are <strong>instance</strong> <strong>fields</strong>.</li><li>To avoid any ambiguities, any <strong>function</strong> defined within a <strong>class</strong> will be known as <strong>method</strong>.</li><li>You define the <strong>constructor</strong> of the <strong>class</strong> with a special (built-in) <strong>method</strong> named __init__.</li><li>All Instance fields should be defined within constructor (i.e., __init__ <strong>method</strong>).</li><li><strong>Method</strong> in a class can either be an <strong>instance-method</strong> (a.k.a. <strong>static-method</strong>) or <strong>class-method</strong>. What make them different is that an instance-method cannot be called directly from the class (i.e., we must call any instance-methods from an instance created from that class), while a class-method can be called directly from the class (i.e., without creating any instance). Same as what I explained on the <strong>instance field</strong> vs <strong>class field</strong>.</li><li>Any <strong>instance-methods</strong> within a <strong>class</strong> must have one special parameter namely self, and it must be defined as the first parameter before other parameters are defined. In our sample for the CustomerAccount class, withdraw, deposit, and current_balance are the <strong>instance-methods</strong>.</li><li>Any <strong>class-methods</strong> can be defined with “NO” self parameter at all. In our sample for the CustomerAccount class, compare_customer_balance is a <strong>class-method</strong>.</li></ol><p>And below is the code snippet on how to use the CustomerAccount class along with some comments to describe on what each statement is doing:</p><pre># use class attribute / field<br># notice that you can directly access the class attribute <br># without creating any instance<br>print(f&quot;Welcome to {CustomerAccount.bank_name}!\n&quot;)<br><br># creating two CustomerAccount instances / objects by calling the class&#39;s constructor<br># (i.e. the  __init__ method)<br>first_customer = CustomerAccount(&quot;911007212&quot;, &quot;DEPOSIT_ACCOUNT&quot;, 0)<br>second_customer = CustomerAccount(&quot;911007213&quot;, &quot;DEPOSIT_ACCOUNT&quot;, 100000)<br><br># try to withdraw an amount of $70,000 from first customer&#39;s account<br>try:<br>  first_customer.withdraw(70000)<br>except Exception as e:<br>  print(f&quot;{e}&quot;)<br><br># check first customer&#39;s balance<br>print(first_customer.current_balance())<br><br># deposit $90,000 to customer&#39;s first account<br>first_customer.deposit(90000)<br><br># print out first and second customer&#39;s current balance<br>print(f&quot;First customer current balance is: {first_customer.current_balance()}&quot;)<br>print(f&quot;Second customer current balance is: {second_customer.current_balance()}&quot;)<br><br># compare two customer&#39;s balance of account and returns the greater one.<br># (calling CustomerAccount&#39;s class method directly without creating an instance)<br>print(CustomerAccount.compare_customer_balance(first_customer, second_customer))</pre><p><strong>&gt; Python Built-in Methods</strong></p><p>Next, let’s also discuss on some <em>built-in</em> <strong>methods</strong> those will be automatically inherited by any class we created in Python. Each of these what being also known as “<strong>dunder</strong>” (<em>double-underscore</em>) <strong>methods</strong> has their internal default implementation that we can override by writing our custom logic inside, and that’s what make them so special 😼.</p><p>Note that I’m not going to discuss all of those built-in methods here since there are so many of them. Yet, I merely discuss on those that I personally used frequently as follow:</p><p>__str__(self) <br>→ By default, this special method will be called by the Python interpreter when you print the class object (instance) through a print statement as what we saw earlier in our code snippet as follow:</p><pre>print(Customer.compare_customer_balance(first_customer, second_customer)) </pre><p>If you run the above statement, you’ll get more or less something as shown below:</p><pre>&lt;__main__.CustomerAccount object at 0x104276690&gt;</pre><p>As we can see that by default the python interpreter will implicitly invoke the <em>built-in</em> __str__(self) method, and the default implementation for this <em>built-in</em> method was to return the string representation of the Class’s object memory location. We can override this default behavior by writing our custom logic as follow (I deliberately hide some of the lines of code for brevity):</p><pre>class CustomerAccount:<br><br>  # __init__ method goes here<br><br>  # other methods are written here<br><br>  def __str__(self):<br>    return f&quot;\nAccount Number: {self.acc_no}\nType of Account: {self.acc_type}\nCurrent Balance: {self.balance}&quot;</pre><p>__lt__(self, other)<br>→ This <em>built-in </em>method can be used to define the behavior for the less-than operator ( &lt; ). For example if we’re looking to compare the two instances of the previous Customer objects defined in our as below:</p><pre>print(first_customer &lt; second_customer)</pre><p>The Python interpreter will implicitly call the built-in __lt__(self, other) method, and it’s going to raise a runtime exception like:</p><pre>    print(first_customer &lt; second_customer)<br>          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>TypeError: &#39;&lt;&#39; not supported between instances of &#39;CustomerAccount&#39; and &#39;CustomerAccount&#39;</pre><p>Since there’s no way for the interpreter to know how to compare these two objects. To overcome this, we can write our custom implementation logic as below:</p><pre>class CustomerAccount:<br><br>  # __init__ method goes here<br><br>  # other methods are written here<br><br>  def __str__(self) -&gt; str:<br>    return f&quot;\nAccount Number: {self.acc_no}\nType of Account: {self.acc_type}\nCurrent Balance: {self.balance}&quot;<br><br>  def __lt__(self, other) -&gt; bool:<br>    return True if self.balance &lt; other.balance else False</pre><p>__eq__(self, other)<br>→ This <em>built-in </em>method is used to compare whether two instances of the same class are equal or not, i.e. equality operator ( == ). The default behavior will be to do the comparison based on the memory address. For example given this following code:</p><pre># creating two CustomerAccount instances / objects by calling the class&#39;s constructor<br># (i.e. the  __init__ method)<br>first_customer = CustomerAccount(&quot;911007212&quot;, &quot;DEPOSIT_ACCOUNT&quot;, 0)<br>second_customer = CustomerAccount(&quot;911007213&quot;, &quot;DEPOSIT_ACCOUNT&quot;, 100000) <br>third_customer = CustomerAccount(&quot;911007212&quot;, &quot;DEPOSIT_ACCOUNT&quot;, 50000)<br><br>print(first_customer == third_customer)</pre><p>Running the above code will give us false being printed on the terminal because the first_customer and third_customer are different instances / objects stored inside the memory. Hence, false will be returned when these two objects being compared to each other. <br>Now, let’s override this default behavior by overriding the built-in __eq__(self, other) method in our CustomerAccount class.</p><pre>class CustomerAccount:<br><br>  # __init__ method goes here<br><br>  # other methods are written here<br><br>  # other &quot;dunder&quot; methods are written here<br><br>  def __eq__(self, other) -&gt; bool:<br>    return True if self.acc_no == other.acc_no \<br>      and self.acc_type == other.acc_type else False</pre><p>Now, we’ll get true printed within our terminal if we’re running the same code as before since we evaluate the customer account based on their <strong>account number</strong> ( acc_no ) and <strong>account type </strong>( acc_type ) irrespective that other fields having different values.</p><p>__call__(self, *args, **kwargs)<br>→ This will enable our instance class to be called as a function.</p><p>So…, given our code snippet below:</p><pre># creating two CustomerAccount instances / objects by calling the class&#39;s constructor<br># (i.e. the  __init__ method)<br>first_customer = CustomerAccount(&quot;911007212&quot;, &quot;DEPOSIT_ACCOUNT&quot;, 0)<br>second_customer = CustomerAccount(&quot;911007213&quot;, &quot;DEPOSIT_ACCOUNT&quot;, 100000) <br><br>first_customer()<br>second_customer()</pre><p>If we’re trying to run the code now, it will raise a TypeError exception with a message: CustomerAccount object is not callable. <br>In order to address this issue, we can define our custom __call__(self, *args, **kwargs) method within our CustomerAccount class as follow:</p><pre>class CustomerAccount:<br><br>  # __init__ method goes here<br><br>  # other methods are written here<br><br>  # other &quot;dunder&quot; methods are written here<br><br>  def __call__(self, *args, **kwargs):<br>    print(self)</pre><p><strong>&gt; Class “Inheritance” and “Polymorphism” in Python</strong></p><p>Now, let’s discuss about how to apply inheritance in Python class. <br>Given that we need to store all personal information for our customer such as first-name, last-name, gender, etc.. we’re going to create another class to represent these attributes in another class named Customer.</p><pre>from datetime import date<br><br>class Customer:<br>  <br>  def __init__(self, fname: str, lname: str, gender: bool, dob: date):<br>    self.fname = fname<br>    self.lname = lname<br>    self.gender = gender<br>    self.dob = dob<br><br>  def register(self):<br>    print(f&quot;Registered {self.lname}, {self.fname} into the system.&quot;)<br><br>  def __str__(self):<br>    return f&quot;\nCustomer Fullname: {self.fname} {self.lname}\n\<br>Gender: {&#39;Male&#39; if self.gender is True else &#39;Female&#39;}\nDate of Birth: {self.dob}&quot;</pre><p>And we’d like to bind our previous CustomerAccount class to this newly created Customer class. There are several ways for doing this, but in this particular context I would opt to change (refactor) our CustomerAccount class to be a child of the Customer class, so the CustomerAccount will implicitly has all attributes / members of it’s parent class (i.e., Customer class). Following is our CustomerAccount class after being refactored:</p><pre>from datetime import date<br><br>class CustomerAccount(Customer):<br><br>  def __init__(self, fname: str, lname: str, gender: bool, dob: date, \<br>      acc_no: str, acc_type: str, balance: float):<br>    super().__init__(fname, lname, gender, dob)<br>    self.acc_no = acc_no<br>    self.acc_type = acc_type<br>    self.balance = balance<br><br>  def __str__(self):<br>    return f&quot;{super().__str__()}Account Number: {self.acc_no}\n\<br>Type of Account: {self.acc_type}\nCurrent Balance: {self.balance}&quot;<br><br>  # rest of the methods here</pre><p>As we can see, we just need to put the parent class name (i.e. Customer) surrounded with parentheses after the child’s class name (i.e. CustomerAccount). Another important thing to mention here is that we also need to adjust the __init__ method of child class by providing all inherited fields from the parent class ( fname, lname, gender, and dob ) and call the parent’s class __init__ method through super().__init__ in order to set each value of the all inherited fields that it got from the parent class. <br>There’s another way for doing this in a much cleaner way later once we get into the <strong>decorator</strong> topic 😼.</p><p>Other than using any existing functionalities provided by the super (parent) class, with respect to the class behaviors… there are some benefits that we can get through inheritance as follow:</p><ol><li>Extend (enrich) the existing class functionalities. As an example, we can add a new functionality to calculate tax into the CustomerAccount class.</li><li>Override the existing class functionalities that was inherited from the parent class.</li></ol><p>Check these 2 following code snippets:</p><pre>class CustomerAccount(Customer):<br>  <br>  # disclaimer (this doesn&#39;t represent a real bank name)  <br>  bank_name = &quot;Bank-RUPT&quot;<br><br>  # __init__ method goes here<br><br>  # this method will override it&#39;s parent `register` method<br>  def register(self):<br>    print(f&quot;Opened a new bank account for {self.lname}, {self.fname}.\n&quot;)<br><br>  # other methods are written here</pre><pre>from typing import List<br><br>customers: List[Customer] = list()<br><br>customers.append(Customer(&quot;Go Kou&quot;, &quot;Son&quot;, True, None))<br>customers.append(CustomerAccount(\<br>  &quot;Yauri&quot;, &quot;Attamimi&quot;, True, None, &quot;911212707&quot;, &quot;DEPOSIT&quot;, 100000))<br><br>for customer in customers:<br>  customer.register()</pre><p>When you run the code, you’ll get two different outputs from each customer’s register method depends on each runtime object’s type it holds. This is one of the feature provided by what so called as “<strong>Polymorphism</strong>”.</p><p><strong>&gt; Class “Encapsulation”” in Python</strong></p><p>As a quick refreshment, “<strong>Encapsulation</strong>” essentially is a mechanism that is used for hiding the information. In the OOP context, it means to hide object’s internal representation or state implementation details from the outside.<br>In essence, we can achieve this in most languages (e.g., Java, Typescript, ECMAScript, etc) through what so-called access modifier / control specifier, i.e. <strong>public</strong>, <strong>protected</strong>, and <strong>private</strong>. However, what make python a bit different from those languages is that Python doesn’t explicitly use those keywords, instead it uses semantics as follow:</p><ul><li>By default, all attributes / fields and methods defined within a class will be treated as public. Hence they can be accessed directly from the outside.</li><li>To make either an attribute or method as protected, use single under-score ( _ ) as the prefix.</li><li>To make either an attribute or method as private, use double under-score ( __ ) as the prefix</li></ul><p>Let’s modify both our Customer and CustomerAccount classes as follow:</p><ol><li>Change the Customer date of birth ( dob ) instance field and the CustomerAccount instance field for balance to private attributes so they can’t be accessed directly from the outside, and</li><li>Provide a <strong>setter</strong> (<em>mutator</em>) and <strong>getter</strong> (<em>accessor</em>) methods so that any client’s code that need to access these attributes can access it from these respective methods.</li></ol><pre>class Customer:<br><br>  def __init__(self, fname: str, lname: str, gender: bool):<br>    self.fname = fname<br>    self.lname = lname<br>    self.gender = gender<br>    self.__dob = None<br><br>  def set_dob(self, dob):<br>    self.__dob = dob<br><br>  def get_dob(self):<br>    return self.__dob<br><br>  def register(self):<br>    print(f&quot;Registered {self.lname}, {self.fname} into the system.&quot;)<br><br>  def __str__(self):<br>    return f&quot;\nCustomer Fullname: {self.lname}, {self.fname}\n\<br>      Gender: {&#39;Male&#39; if self.gender is True else &#39;Female&#39;}\n\<br>      Date of Birth: {self.__dob}\n&quot;<br><br><br>class CustomerAccount(Customer):<br><br>  # disclaimer (this doesn&#39;t represent a real bank name)<br>  bank_name = &quot;Bank-RUPT&quot;<br><br>  def __init__(self, fname: str, lname: str, gender: bool, \<br>      acc_no: str, acc_type: str):<br>    super().__init__(fname, lname, gender)<br>    self.acc_no = acc_no<br>    self.acc_type = acc_type<br>    self.__balance = 0<br><br>  # this method will override it&#39;s parent `register` method<br>  def register(self):<br>    print(f&quot;Opened a new bank account for {self.lname}, {self.fname}.&quot;)<br><br>  def current_balance(self):<br>    return self.__balance<br><br>  def withdraw(self, amt: float):<br>    if self.__balance &lt; amt:<br>      raise Exception(&quot;Balance is not sufficient!&quot;)<br><br>    self.__balance -= amt<br>    print(f&quot;{amt} is withdrawn from your account.&quot;)<br>    print(f&quot;Your balance now is {self.__balance}&quot;)<br><br>  def deposit(self, amt: float):<br>    if amt &lt;= 0:<br>      raise Exception(&quot;Deposit amount should be greater than 0.00!&quot;)<br><br>    self.__balance += amt<br>    print(f&quot;{amt} has been added into your account.&quot;)<br>    print(&quot;Your balance now is {self.__balance}&quot;)<br><br>  # Other methods written here</pre><p>And following is the code snippet to test those two modified classes:</p><pre>customer = CustomerAccount(&quot;Bruce&quot;, &quot;Lee&quot;, True, &quot;911212009&quot;, &quot;DEPOSIT&quot;)<br>print(customer)<br><br>customer.set_dob(date(1973, 7, 20))<br>customer.deposit(1000000)<br><br>print(customer)</pre><p>That’s the end of the OOP topic for Python, and you can grab the latest code for this OOP section from my <a href="https://github.com/yauritux/blog-python-journey/tree/part-ii-oop">GitHub</a>.</p><h4>Decorator in Python</h4><p>“<strong>Decorator</strong>” is one of the design pattern as promoted by the famous <a href="https://www.digitalocean.com/community/tutorials/gangs-of-four-gof-design-patterns">Gang-of-Four (GoF) Design Patterns</a> book. It falls under the category of “<a href="https://refactoring.guru/design-patterns/structural-patterns">Structural Design Pattern</a>”. See its definition from Wikipedia below:</p><blockquote>In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other instances of the same class. — Wikipedia</blockquote><p>In essence, <strong>decorator</strong> is useful to enrich the behavior / functionality of an object (instance) without impacting other objects / instances of the same class.</p><p>There are two types of <strong>decorator</strong> in Python, i.e. “<strong>Function Decorator</strong>” and “<strong>Class Decorator</strong>”.</p><p><strong>&gt; “Function Decorator” in Python</strong></p><p>Let’s say i have a function that returns sum of 1 to 1_000_000 below:</p><pre>def sum():<br>  sum = 0<br>  for i in range(1000000):<br>    sum += i<br>  return sum<br><br>if __name__ == &quot;__main__&quot;:<br>  print(sum)</pre><p>Running the program and we’ll get output something similar to this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/654/1*6WQ22hQs9mb6BUPL4Li0Vg.png" /></figure><p>Now, let’s say if i want to measure the performance of the function by subtracting the finished time against its starting time. However, I don’t want to modify my original sum function, instead I’m looking to wrap my existing sum function with another function that I build as a <strong>decorator</strong>. See the following code:</p><pre>import time<br><br>def processing_time():<br>  <br>  def wrapper(fn):<br>    start = time.process_time()<br>    print(&#39;Starting at&#39;, start)<br>    print(fn())<br>    end = time.process_time()<br>    print(&#39;finished at&#39;, end)<br>    print(&#39;process took&#39;, &quot;{:.8f}&quot;.format(float(end - start)), &quot;s&quot;)<br><br>  return wrapper<br><br>def sum():<br>  sum = 0<br>  for i in range(1000000)<br>    sum += i<br><br>  return sum<br><br>if __name__ == &quot;__main__&quot;:<br>  sum = processing_time(sum)<br>  sum()</pre><p>Running the program will give you something similar as follow:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/624/1*agXRowfsWttmJf8zHPXYfg.png" /></figure><p><strong>Some key-takeaways here:</strong></p><ul><li>We create another function called processing_time(), and basically this is our <strong>decorator</strong> function.</li><li>Within our decorator function, we define another inner function called wrapper that will take any function as it’s parameter as denoted by fn, and this is feasible because Python treat function as a <strong>first-class-object</strong> (a.k.a. <em>first-class-citizen</em>) which make it can be passed anywhere within our code (e.g., as a function argument, as a returned value, etc).</li><li>Inside the wrapper(fn) function, we can basically write any additional logics as we’d like to before and/or after calling our <em>decorated</em> function which is sum in this context. In our case, we capture the <strong>start-time </strong>before calling the sum function, and finalize with capturing the <strong>end-time</strong> and also performing a basic subtraction (i.e., end-start). Then we return the wrapper function to be automatically invoked later by the Python interpreter.</li><li>Last but not least, there are few ways for us to test our <strong>decorator</strong>. The first one as shown in our sample above is by passing our sum function as an argument into ourprocessing_time <strong>decorator</strong> function. Another way that we can do is through an <em>annotation</em> tag (similar like <strong>Annotation</strong> in <strong>Java</strong>, i.e., @ ). Check the code below and compare it with the previous one without @:</li></ul><pre># our decorator function is written here<br><br>@processing_time # --&gt; apply decorator through &#39;@&#39; tag<br>def sum():<br>  sum = 0<br>  for i in range(1000000)<br>    sum += i<br><br>  return sum<br><br>if __name__ == &quot;__main__&quot;:<br>  sum() # --&gt; here we just call our decorated function without wrapping it anymore</pre><p>Now let’s see how we can utilize ourprocessing_timedecorator function to our previous sample on the CustomerAccount class, in particular to both method deposit and withdraw. Check the code below:</p><pre>import time<br><br>def processing_time(fn):<br><br>  def wrapper(*args, **kwargs):<br>    start = time.process_time()<br>    print(&quot;starting at&quot;, start)<br>    print(fn(*args, **kwargs))<br>    end = time.process_time()<br>    print(&quot;finished at&quot;, end)<br>    print(&quot;process took&quot;, &quot;{:.8f}&quot;.format(float(end - start)), &quot;s&quot;)<br><br>  return wrapper<br><br><br>class CustomerAccount(Customer):<br><br>  # disclaimer (this doesn&#39;t represent a real bank name)<br>  bank_name = &quot;Bank-RUPT&quot;<br><br>  # init method goes here<br><br>  # other methods were hidden for brevity<br><br>  @processing_time<br>  def withdraw(self, amt:float):<br>    if self.__balance &lt; amt:<br>      raise Exception(&quot;Balance is not sufficient!&quot;)<br><br>    self.__balance -= amt<br>    print(f&quot;{amt} is withdrawn from your account.&quot;)<br>    print(f&quot;Your balance now is {self.__balance}&quot;)<br><br>  @processing_time<br>  def deposit(self, amt: float):<br>    if amt &lt;= 0:<br>      raise Exception(&quot;Deposit amount should be greater than 0.00!&quot;)<br><br>    self.__balance += amt<br>    print(f&quot;{amt} has been added into your account.&quot;)<br>    print(f&quot;Your balance now is {self.__balance}&quot;)</pre><p>Did you notice some changes in our processing_time decorator function ?</p><p>As you know that both our CustomerAccount.withdraw and CustomerAccount.deposit methods have parameter|s (i.e. amt). Hence, we can’t apply the same processing_time decorator function as before. It will definitely raise a runtime error (i.e. TypeError ) if we force to use the same processing_time as before.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lQf_0L6XrajW3dcDKY3tGw.png" /></figure><p>Therefore we need to “tweak” a little bit our processing_time decorator function as shown above. If you are curious about args and kwargs usages in python, you can refer to this <a href="https://www.geeksforgeeks.org/args-kwargs-python/">link</a>.</p><p><strong>&gt; “Class Decorator” in Python</strong></p><p>In essence, once we understand the concept of “<strong>Function Decorator</strong>”, this part should be quite straightforward for us. What make this “<strong>Class Decorator</strong>” a bit different is that when we decorate a function with a class, the function is automatically passed as the first argument to the class init constructor, hence we set this function as one of the attribute of our class decorator’s object. In other words, when we decorate a function / method with a “<strong>Class Decorator</strong>”, that particular function / method becomes an instance of the “<strong>Class</strong> D<strong>ecorator</strong>”. With this being said, you have to be careful in the case of any attributes being accessed by your instance method won’t be available anymore within the “Class Decorator”. <br>Yet, it won’t be a problem in case you apply the “Class Decorator” to a function or static method.</p><p>To see how this works, let’s add another function (static method) into our CustomerAccount class that takes CustomerAccount object as it’s argument and calculate and returns the customer’s credit score as shown below:</p><pre>class CustomerAccount(Customer):<br><br>  # other lines were hidden for brevity<br><br>  def calculate_credit_score(cust) -&gt; float:<br>    if cust.current_balance() &gt; 0 and cust.current_balance() &lt; 1000:<br>      return 0.01<br>    if cust.current_balance() &gt; 1000 and cust.current_balance() &lt;= 10000:<br>      return 0.05<br>    if cust.current_balance() &gt; 10000 and cust.current_balance() &lt;= 50000:<br>      return 0.10<br>    if cust.current_balance() &gt; 50000 and cust.current_balance() &lt;= 100000:<br>      return 0.25<br>    if cust.current_balance() &gt; 100000:<br>      return 0.50<br><br>    return 0.00</pre><p>Next, let’s create a new “<strong>Class Decorator</strong>” that writes into a log file named log.txt.</p><pre>from datetime import datetime<br>import time<br><br><br>class Logger:<br>  <br>  def __init__(self, fn):<br>    self._fn = fn<br><br>  def __call__(self, *args, **kwargs):<br>    start = time.process_time()<br>    file = open(&quot;log.txt&quot;, &quot;a+&quot;)<br>    result = self._fn(*args, **kwargs)<br>    output = f&quot;{datetime.now()} - {self._fn.__name__} is executed. Time taken: {float(time.process_time() - start)} s\n&quot;<br>    file.write(output)<br>    file.close()<br>    return result</pre><p>and apply this decorator into our calculate_credit_score static method.</p><pre>class CustomerAccount(Customer):<br><br>  # other codes here<br><br>  @Logger # --&gt; our class decorator<br>  def calculate_credit_score(cust) -&gt; float:<br>    # logics here</pre><p>Running the program should produce one file named log.txt in your project root folder contains something similar as follow:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JCa9oRXSzd6n00tMDHeT9Q.png" /></figure><p>That’s all for “Decorator in Python”. <br>As usual, the latest code for this can be grab from my <a href="https://github.com/yauritux/blog-python-journey/tree/part-ii-decorator">GitHub</a>.</p><h4>Python List Comprehension</h4><p>Basically “<strong>List Comprehension</strong>” is just a syntactic sugar for creating an iterable object (e.g. list, tuple, dictionary, and string) in Python. In most cases, it helps us to make our code more concise and clear. <br>The basic structure for “<strong>List Comprehension</strong>” is as follows:</p><pre>[expression for item in iterable if condition]</pre><ul><li><strong>expression:</strong> <br>the value or transformation to apply to each item in the iterable object.</li><li><strong>for item in iterable:<br></strong>the loop that iterates over each element in the iterable.</li><li><strong>if condition:<br>(</strong>Optional) a filter that selects elements to be included in the new list.</li></ul><p>For instance, to create a list of squares from number 0 to 9, some folks might be writing something as follows:</p><pre>squares = []<br>for i in range(10):<br>  squares.append(i**2)<br><br>print(squares) # output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</pre><p>with “<strong>List Comprehension</strong>”, we can write something more concise and clear as below:</p><pre>squares = [i**2 for i in range(10)] <br>print(squares) # output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</pre><p>we can also add a filter based on <strong>if condition</strong>.</p><pre>squares = [i**2 for i in range(10) if i % 2 == 0]<br>print(squares) # output: [0, 4, 16, 36, 64]</pre><p>How about working with string ? sure we can 👇</p><pre>uppercase = [char.upper() for char in &#39;python&#39;]<br>print(uppercase) # output: [&#39;P&#39;, &#39;Y&#39;, &#39;T&#39;, &#39;H&#39;, &#39;O&#39;, &#39;N&#39;]</pre><p>There’s no limitation on the number of <strong>`for item in iterable`</strong> we use. Check the code below that utilize “<strong>List Comprehension</strong>” for flattening the two-dimensional list (<em>Matrix</em>).</p><pre>matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]<br>flattened = [num for row in matrix for num in row]<br>print(flattened) # output: [1, 2, 3, 4, 5, 6, 7, 8, 9]</pre><p>Compare with how we use traditional loop to achieve the same thing below:</p><pre>matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]<br>flattened = []<br>for row in matrix:<br>  for num in row:<br>    flattened.append(num)<br><br>print(flattened) # output: [1, 2, 3, 4, 5, 6, 7, 8, 9]</pre><p>Over to you now, which one you’ll choose ? 😼</p><p><strong>&gt; Rules of Thumb</strong></p><p>There are several rules of thumb we might consider when deciding between “<strong>List Comprehension</strong>” or traditional way (e.g. loop) for creating list.</p><ol><li><strong>Readability</strong><br><strong>List Comprehension:</strong><br>- Use this merely simple transformations and/or filters.<br>- Make sure that your list comprehension is easy to understand.<br>- Avoid using list comprehension if they become too complex and hard to read.<br><strong>Traditional Loops:</strong><br>- Use this if the logic is complex or requires multiple steps.<br>- Traditional loop can be more readable for complicated operations, as they allow for better structuring and commenting and easier to debug.</li><li><strong>Performance</strong><br><strong>List Comprehension:</strong><br>- Generally faster due to its internal optimizations, yet please make sure that your logic is not too complex to be digested by other fellow engineers.<br><strong>Traditional Loops:</strong><br>- Can be more flexible and easier to optimize for specific cases where list comprehensions may fall short.<br>- Useful when additional operations or function calls are needed within the loop.</li><li><strong>Side Effects</strong><br><strong>List Comprehensions:</strong><br>- Avoid using this if the operation has side effects (e.g., modifying external variables, I/O operations)<br><strong>Traditional Loops:</strong><br>- Use this if the operation has side effects to make the code clearer and easy-to-maintain.</li></ol><h4>Generators</h4><p>In essence, “generators” in Python is considered as a fancy-way to create iterators, which are object that holds a sequence of values and provide sequential traversal through a collection of items such as lists, tuples, sets, and dictionaries.</p><p>“Generators” make it easy to work with data one piece at a time (a.k.a. <strong>lazy-loading</strong>), especially if we don’t want to load everything into memory at once (a.k.a. <strong>eager-loading</strong>). So, “generators” give us flexibility to iterate over data without creating a complete list in memory, instead..they produce values one at a time as we need them. Thereby, “generators” don’t calculate values until we actually need them (<strong>lazy evaluation</strong>) which save memory a lot for us.</p><p><strong>&gt; Writing “Generator” Function</strong></p><p>Let’s create a generator function that produces numbers from 1 to 10, one at a time.</p><pre>def number_generator():<br>  for i in range(1, 11):<br>    yield i</pre><p>Or, we can also use yield from with list comprehensionas follow:</p><pre>def number_generator():<br>  yield from [i for i in range(1, 11)]</pre><p>Notice the yield i line — this is what makes number_generator function a generator. When we call yield, Python pauses the function and saves the current state, and i is returned to the caller. Thus, yield keyword is the core of a generator. When a function has yield instead of return, it becomes a generator function.</p><p>Please also note that yield can merely be defined within a function. You’ll get something such as SyntaxError : yield outside function exception if you’re trying to define / call yield without / outside a function.</p><p><strong>&gt; Using the “Generator” Function</strong></p><p>Using loop to access generator:</p><pre># Create a generator<br>gen = number_generator()<br><br># Use loop to access values produced by the generator<br>for number in gen:<br>  print(number)</pre><ol><li>When the for loop starts, gen begins at the first value (1).</li><li>It calls yield and outputs 1, then pauses.</li><li>Each time the loop continues, the generator resumes from where it left off, producing 2, 3, and so on until 10.</li><li>After yielding 10, the generator ends.</li></ol><p>Using next to access generator:</p><pre>gen = number_generator()<br>print(next(gen)) # Output: 1<br>print(next(gen)) # Output: 2<br>print(next(gen)) # Output: 3<br><br># and keep calling `next` until we get a StopIteration exception</pre><p><strong>&gt; Benefits of Generators</strong></p><ul><li><strong>Memory Efficiency:</strong> They don’t store all values in memory since they generate each value as we need it.</li><li><strong>Lazy Loading / Lazy Evaluation:</strong> Ideal for large datasets (potentially infinite datasets), as they compute values only as required.</li><li><strong>Simplifies Code:</strong> They’re great way to handle sequences that are calculated on-the-fly without needing complex data structures.</li></ul><h4>Context Manager</h4><p>It’s common that writing or building an application will be often dealing with managing I/O resources such as database, file, etc. The usage of these resources are most likely cannot be avoided since we need to maintain / persist the data either in files or databases. However, these resources are limited in supply. Therefore, we need to be careful in making sure to release these resources after usage. If they are not released, it will lead to resource leakage and may cause the system either slow down or crash (unavailable). Traditionally, we need to write some cleanup code by ourselves in order to free/release all resources after their usages which is pretty tedious and don’t be surprised that we might also forget to write this cleanup code that can lead to resource leakage as mentioned earlier.</p><p>In Python, there’s a mechanism that can help us to automate setup and teardown resources with the usage of the <strong>context managers</strong> that facilitate the proper handling of resources.</p><p><strong>&gt; File Handling without Context Manager</strong></p><p>Check the following example on how we handle manually the cleanup code (i.e., closing the file) after its usage:</p><pre>file = open(&quot;my_file.txt&quot;, &quot;r&quot;, encoding=&quot;utf-8&quot;)<br>for line in file:<br>  print(line)<br><br>file.close() #you close the file after the usage which sometimes this can be forgotten</pre><p><strong>&gt; File Handling with Context Manager</strong></p><p>Check the following example on how we use <strong>context managers</strong> to automatically handling file resources with the help of with statement. With this approach, the file will be automatically released after its usage, and we don’t need to explicitly write any logic for it.</p><pre>with open(&quot;my_file.txt&quot;, &quot;r&quot;, encoding=&quot;utf-8&quot;) as f:<br>  print(f.read())</pre><p><strong>&gt; Creating a Custom Context Manager</strong></p><p>We can also create our own context manager. When creating <strong>Context Manager </strong>using class, we need to ensure that the class has special methods (<em>dunder</em> methods) namely __enter__() and __exit__().</p><p>The __enter__() returns the resource that needs to be managed while the __exit__() does not return anything but used to performs the cleanup operations (i.e., release any resources after the usages). Check the example below:</p><pre>class ContextManager():<br>  def __init__(self):<br>    print(&#39;init method called&#39;)<br>  <br>  def __enter__(self):<br>    print(&#39;enter method called&#39;)<br>    return self<br><br>  def __exit__(self, exc_type, exc_value, exc_traceback):<br>    print(&#39;exit method called&#39;)<br><br><br>with ContextManager() as manager:<br>  print(&#39;with statement block&#39;)</pre><p>The above code will be creating an object of type <strong>ContextManager</strong> that is assigned to variable named manager. And, when the program is running, these following will be get executed in sequence:<br>- __init__()<br>- __enter__()<br>- statement body, i.e. code inside the with block<br>- __exit__()</p><p>Using the same approach, we can create our custom <strong>ContextManager</strong> to handle file operation as follow:</p><pre>class FileManager:<br>  def __init__(self, filename, mode):<br>    self.filename = filename<br>    self.mode = mode<br>    self.file = None<br><br>  def __enter__(self):<br>    self.file = open(self.filename, self.mode, encoding=&#39;utf-8&#39;)<br>    return self.file<br><br>  def __exit__(self, exc_type, exc_value, exc_traceback):<br>    self.file.close()<br><br>with FileManager(&quot;my_file.txt&quot;, &quot;r&quot;) as f:<br>  print(f.read())</pre><p>And following for another example on how to create custom ContextManager for dealing with mongo database:</p><pre>from pymongo import MongoClient<br><br>class MongoDBManager():<br>  def __init__(self, hostname: str, port: str):<br>    self.hostname = hostname<br>    self.port = port<br>    self.connection = None<br><br>  def __enter__(self):<br>    self.connection = MongoClient(self.hostname, self.port)<br>    return self.connection<br><br>  def __exit__(self, exc_type, exc_value, exc_traceback):<br>    self.connection.close()<br><br>with MongoDBManager(&#39;localhost&#39;, &#39;27017&#39;) as mongo:<br>  collection = mongo.connection.TestDb.test<br>  data = collection.find({&quot;_id&quot;: 1})<br>  print(data.get(&#39;name&#39;))</pre><p>The next big thing which is coming up soon as you might guessed already: <strong>Asynchronous Programming </strong>:-). <br> → Stay tuned…</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=36b1094f32d6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DDD Part VI]]></title>
            <link>https://yauritux.medium.com/ddd-part-vi-ce543a0f1cbe?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/ce543a0f1cbe</guid>
            <category><![CDATA[cqrs]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <category><![CDATA[event-sourcing]]></category>
            <category><![CDATA[microservices-pattern]]></category>
            <category><![CDATA[software-design-patterns]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Thu, 22 Apr 2021 05:01:46 GMT</pubDate>
            <atom:updated>2024-05-06T16:55:13.403Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>ES and CQRS Implementation</blockquote><p>Hopefully it’s not that late now to write the last part of my DDD blog series. For those of You whom somehow got into this part without any chance to have a look into the other parts, You can check them out by starting from <a href="https://blog.yauritux.link/ddd-part-i-introduction-cabab1d2e27d">here</a>.</p><p><a href="https://martinfowler.com/eaaDev/EventSourcing.html">ES</a> (Event-Sourcing) and <a href="https://martinfowler.com/bliki/CQRS.html">CQRS</a> (Command-Query-Responsibility-Segregation) are not the new kids on the block. They have been there for some couple years. As for me, the first time I heard about these stuff was go back in the year of 2012. Even during that time I also knew that both (particularly ES) had been there for … not sure when exactly. Since then, I’ve been getting a chance to playing with these two “guys” several times, and lucky enough to failed several times as well :-). I always believe that from failures, we can learn so many good things about why they failed, which eventually can bring us to the next level of better understanding. That’s why as a good engineer and architect, we used to do ‘trial and error’ anyway. Even some of the great leaders from a well-known Companies won’t argue me on this matter :-) (See it <a href="https://hbr-org.cdn.ampproject.org/c/s/hbr.org/amp/2017/11/how-coca-cola-netflix-and-amazon-learn-from-failure">here</a>).</p><p>Back to our main topic, I won’t talk too much the nitty-gritty details about what are ES and CQRS ?, how are they working together to achieve their goals ?, and what are the benefits and drawbacks of using both ? particularly in our micro-services architecture. Nowadays you can find a lot of information about those two from the internet. However, I’d like to share that both actually came from different perspective and coined by different guy. I figured out that ES itself was brought from the concept of a “Journal Entry” in the “Accounting” world. So essentially, You can use CQRS without ES at all (even in monolith application), and similarly you can use optionally choose to implement ES without CQRS at all. However, there’s a saying that “You have to implement CQRS when you’re doing ES to make it easier”. This saying most likely came from someone that already tried to implement ES without CQRS, so they know exactly how difficult it is to use ES with “No CQRS”.</p><p>I had a chance to use CQRS several times in my non-ES architecture, yet I straightly use ES and CQRS together for my ES implementation due to that wise saying since I don’t want to reinvent the wheel.</p><p>With that being said, I will be using Java for our implementation since there’s one cool framework named <a href="https://axoniq.io/">Axon</a> which already handled all of the technical complexities for us, so we can keep focus with the business functionalities to reduce our time-to-market. I’m planning to write another article later to discuss on how we do implement this ES-CQRS without any framework at all (i.e. build our own framework). But let’s use <a href="https://axoniq.io/">Axon</a> for now.</p><p>As we can see from its’ website, <a href="https://axoniq.io/">Axon</a> mainly comes with 2 different flavors: the <a href="https://axoniq.io/product-overview/axon-framework">Axon Framework</a>, and the <a href="https://axoniq.io/product-overview/axon-server">Axon Server</a> which is used as it’s main <a href="https://en.wikipedia.org/wiki/Event_store">event-store</a> and <a href="https://www.enterpriseintegrationpatterns.com/patterns/messaging/MessageBus.html">message bus</a> (command-bus and event-bus).</p><p>If we are searching for the tutorial on how to use this framework, you can find a lot of articles and even YouTube videos. So I think, it won’t be interesting for me to write another article for it. As a contrary, what I’m going to write here was based on my RnD in using this framework without Axon Server at all (we’ll be using PostgresDB as both our command-bus and event-store, and RabbitMQ as our event-bus). In other words, we won’t go with the Axon standard implementation. I was experiencing quite tremendous time to go with this implementation since all of the tips written on the official Axon website were not working as I expected, at least at the time when I’m writing this.</p><p>Enough the chit-chat, let’s discuss now on how we’re going to implement this.</p><h4>Prerequisites</h4><ol><li>Java 11 (as the project that I’m actively working at the moment uses this version).</li><li>SpringBoot Initializr (https://start.spring.io).</li><li>I’m using this <a href="https://www.jetbrains.com/idea/">freakingly awesome IDE</a>, yet any editor should be fine.</li><li>Docker. This one is optional, but I strongly recommend You to use it, especially if you want your machine to be not disrupted by any software installation. The most notably benefit by using it is we can easily switch between different version of software as we need due to its’ isolated environment.</li></ol><h4>Our Project Design</h4><p>For simplicity in showing the concept, we’re going to build a simple user-management-service with two basic features as depicted below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/708/1*mc4JzTB9-Es1b38GrDkuFg.png" /><figcaption>User Management Service</figcaption></figure><p>And based on the Onion Architecture that I had described on the <a href="https://blog.yauritux.link/ddd-part-iii-a4ef18ef9e03">Part 3</a>, here’s what it looks like for our code scaffolding (structure components):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4MYyTeXZLVj8zWYMq0RniA.jpeg" /><figcaption>Our Code Structure Components</figcaption></figure><p>As depicted in the diagram, there’s no Axon server at all, and as replacement we’ll be using these following:</p><ol><li>PostgresDB as our User Event Store, and implicitly as our Command-Bus to dispatch all commands to their respective command handler components (aggregates). This will be representing our <strong>writer</strong> database (the <strong>command</strong> side).</li><li>RabbitMQ as our Event Broker, hence all generated events will be routed to its listeners through this particular component. (We can use Kafka as well for sure, I will cover it later in the next chapter).</li><li>PostgresDB as our User Query Store to store all projections as needed from the business (functional) point-of-view. This will be representing our <strong>read</strong> database (the <strong>query</strong> side).</li></ol><h4>Create Our Project</h4><p>Common way to start creating our project is by generating the project through <a href="https://start.spring.io/">Spring Initializr</a>. For some Java IDE such as IntelliJ IDEA Ultimate, we can create it from there as well. I won’t go details on this since its very straightforward. What I’m going to describe here is that we’re going to have 1 parent pom project with 3 submodules inside respectively for:</p><ol><li><strong>User Core (</strong><strong>usercore)<br></strong>This will be our core domain as represented on the above diagram. As you probably noticed, we have all of our events defined here. The main reason for it because events are something related and specific to the business domain, hence from the onion architecture perspective we have to cover it in the most inner side. And the reason for me to wrap this as an independent submodule is because we can deliver this as a Jar library to be shared later to any systems/parties that have an interest to integrate with our business domain.</li><li><strong>User Command Service (</strong><strong>usercmdsvc)<br></strong>No need for more explanation, as You might probably guess.. this is going to be our <strong>Command</strong> (<em>writer</em>) service, that is letter <strong>C </strong>from<strong> </strong>the <strong>C</strong>QRS perspective.</li><li><strong>User Query Service (</strong><strong>userquerysvc)<br></strong>Our <strong>Query</strong> (<em>reader</em>) service, that is letter <strong>Q</strong> from the C<strong>Q</strong>RS perspective.</li></ol><p><strong>Creating our User Core Module</strong></p><p>We only need to have <strong>lombok</strong> as our dependency for this particular module since this module will merely contains some POJO classes for our Domain Event and Entity, and we want to avoid any <em>boilerplate</em> codes such as <strong>getters</strong> and <strong>setters </strong>to produce much cleaner code<strong>.</strong></p><p>Here’s what our <strong>pom.xml</strong> will be looked like after we create our first module for User Core:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fe0fa1794d4cf98f8465578a6b5e0f92/href">https://medium.com/media/fe0fa1794d4cf98f8465578a6b5e0f92/href</a></iframe><p><strong>Creating our User Command Service</strong></p><p>Similarly, you can fire up another <a href="https://start.spring.io/">Spring Initializer</a> and create our second module for <strong>Command</strong> service. And here’s our <strong>pom.xml</strong> for this particular command service module:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/99407ec1a91a105a6240f8c30b37e4e6/href">https://medium.com/media/99407ec1a91a105a6240f8c30b37e4e6/href</a></iframe><p>Here are some notably dependencies along with their explanation:</p><ol><li><strong>Spring Web</strong> <br><strong>artifact</strong>: org.springframework.boot.spring-boot-starter-web<br>We’re going to expose our API as REST APIs. This is where this particular dependency play its’ role.</li><li><strong>Spring Data JPA<br>artifact: </strong>org.springframework.boot.spring-boot-starter-data-jpa<br>We’re going to use SQL database as our main event-store, that’s the reason we added this dependency for all <a href="https://en.wikibooks.org/wiki/Java_Persistence/What_is_JPA%3F">JPA</a> operation.</li><li><strong>PostgreSQL Driver</strong> <br><strong>artifact</strong>: org.postgresql.postgresql<br>SpringBoot brings the concept of “<a href="https://en.wikipedia.org/wiki/Convention_over_configuration">convention over configuration</a>”, therefore once it detects we have JPA library as one of our dependency, it strongly needs more specific information about what kind of database we’re going to use. Hence we must add this <strong>postgresql</strong> library (depends on our database) as our database driver, or Spring will be complaining later if we don’t specify any database driver within our pom.</li><li><strong>Axon Spring Boot Starter</strong><br><strong>artifact</strong>: org.axonframework.axon-spring-boot-starter<br>Our main library for <strong>Axon framework</strong>. However, we need to exclude axon server connector as specified in the exclude tags, because we’re not going to use <strong>Axon Server</strong>.</li><li><strong>Spring Cloud Stream Binder Rabbit</strong><br><strong>artifact</strong>: org.springframework.cloud.spring-cloud-stream-binder-rabbit<br>We need this library since we use <strong>RabbitMQ</strong> as our <strong>event-broker</strong>. <a href="https://spring.io/projects/spring-cloud-stream">Spring Cloud Stream</a> is very handy since it is agnostic, so in essence we can use it to connect with any <a href="https://en.wikipedia.org/wiki/Message-oriented_middleware">messaging middleware</a>. <br>In our case, we use <strong>Rabbit</strong> as our <strong>binder</strong>, so <strong>Spring</strong> will provide <strong>Rabbits’</strong> specific implementation for us. <br>In the future, if we need to change our messaging middleware to something else like Kafka, we merely need to replace our Rabbit binder with Kafka binder, and the rest of our code will almost still the same.</li><li><strong>User Core<br></strong>This is our first module which we created earlier. We need to include it in our command service since we’re going to use some the domain events and entities from this particular core module.</li><li><strong>Lombok<br></strong>To reduce any <em>boilerplate</em> codes.</li></ol><p><strong>Creating our User Query Service</strong></p><p>Here’s our pom.xml for User Query Service:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c1078e061336a69bd2c6653217576bcc/href">https://medium.com/media/c1078e061336a69bd2c6653217576bcc/href</a></iframe><p>As we can see, we’ve also excluded the Axon server connector from this user query service pom.xml. Another thing which make it different from the user command service pom is that instead of using Spring Cloud Stream, we deliberately use AXON AMQP extension to connect our event handler (listener) to our RabbitMQ. Nonetheless, you can also use Spring Cloud Stream as well. It all depends on You, which one is more convenience for You.</p><p><strong>Creating our Parent Project</strong></p><ol><li>Create a new standard Maven project and give it a name as <strong>user-management-service</strong> (you can skip the archetype selection). You can either use your favorite IDE for this, or simply by executing this following command from your terminal:<br>mvn archetype:generate -DgroupId=com.power \ <br>-DartifactId=user-management-service \<br>-Dversion=1.0.0 -DinteractiveMode=false</li><li>Once the project is created, you can delete the src folder since it’s not needed.</li><li>Move the 3 modules you created earlier (usercore, usercmdsvc, userquerysvc) into this <strong>user-management-service</strong> folder.</li><li>Update your <strong>user-management-service</strong> <strong>pom.xml</strong> to Introduce those 3 modules we created earlier:</li></ol><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bd7d88ea01f4a51f50f7295100716ccd/href">https://medium.com/media/bd7d88ea01f4a51f50f7295100716ccd/href</a></iframe><p>At this point, your project will be looked more or less like this one:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/766/1*ZqlXbSeMngnf7Ufxwp_6RQ.png" /><figcaption>Our Project Structure</figcaption></figure><p>OK, that’s all for the setup. I won’t be going further with the explanation since it’s quite explanatory from the code that <a href="https://github.com/yauritux/user-management-service">you can grab from my GitHub here</a>. Please follow <a href="https://github.com/yauritux">my GitHub account</a> so you’ll get notified for any future update in the code, and feel free to drop me a message in case you have some concerns or constructive feedbacks.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ce543a0f1cbe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DDD Part 5]]></title>
            <link>https://yauritux.medium.com/ddd-part-5-b0caf2437912?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/b0caf2437912</guid>
            <category><![CDATA[domain-driven-design]]></category>
            <category><![CDATA[clean-code-with-golang]]></category>
            <category><![CDATA[clean-code-architecture]]></category>
            <category><![CDATA[software-design]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Tue, 28 Jan 2020 02:34:12 GMT</pubDate>
            <atom:updated>2024-05-06T16:52:41.289Z</atom:updated>
            <content:encoded><![CDATA[<h3>DDD Part V</h3><h4>Code Implementation</h4><p>I’ve just realized that it’s been almost 2 years passed since I wrote <a href="https://blog.yauritux.link/ddd-part-iv-94a8c88504c0">DDD Part IV</a>. I’ve been waiting all these times to write this part. Hopefully, this part will be useful for you, at least for me since i believe that the most effective way to tie your knowledge is by writing and sharing it.</p><p>Some of you whom probably have read my previous series on the DDD, might realized that deliberately i changed a bit the story’s sequences. This was because i got few messages asked me to give the code sample [talk is cheap, show me the code ~ Linus Torvalds] :-). Therefore, i’ll keep the ES and CQRS section for the last part. Another thing, I’ll be using go (golang) here since i’ve been working with it lately. The version that i’m currently working on while writing this article is 1.13.4.</p><p>So, let’s get started…</p><p>For the code implementation, i’m gonna start by implementing some of the functionalities within shopping cart since it’s pretty straightforward. I believe nowadays everyone knows about how it works (at least most of us ever bought something online).</p><p>First and foremost i’m gonna show you below the common processes of shopping cart. Note that what i’ll be showing here is restricted to thebounded context of the shopping cart, means we’ll just focus with the process of how the user/buyer choose the item and adding that particular item into his cart, subsequently continue with checkout. As for the billing/payment part, that will be in the bounded context of payment service. (if you’re neither really familiar nor confidence with what bounded context is, i would suggest you to read the first part <a href="https://medium.com/@yauritux/ddd-part-i-introduction-cabab1d2e27d">here</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PHfu9i2ZZ9PsP00JjDD2Gg.png" /><figcaption>Common Shopping Cart Process</figcaption></figure><p>Worth to mention here, what are highlighted in the grey color were standing outside of our shopping cart bounded context. Hence, we won’t tackle the nitty gritty details of those objects within our code implementation since those things would be in other services (e.g. product catalogue service and user service). Nevertheless, we’ll still be having those objects within our code, in the context of what our shopping cart needs. For instance, we won’t need user credentials information in our shopping cart since that should be catered from the user service context. In essence, we merely need user information which is related to the shopping cart itself, such as: user_session_id, shipping address, billing address (furthermore, address information should also be catered from another service, e.g. : address service even this can be optional).</p><p>Another thing, i won’t be exactly using the onion architecture here. I’ll be using the <a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html">clean code architecture</a> instead as promoted by <a href="https://en.wikipedia.org/wiki/Robert_C._Martin">Robert C.Martin</a> a.k.a. Uncle Bob. IMHO both are quite similar.., they just have different terms to explain the structure of their layers. Nevertheless, i often use all terms from those two architecture interchangeably inside the code. So, don’t get confuse with it.., just trying to focus with the layered architecture and also couple things from these following rules:</p><ul><li>Dependency between layer should be going inward in one direction. As far as i concern, it was designed like this to avoid any <a href="https://en.wikipedia.org/wiki/Circular_dependency">circular dependencies</a>.</li><li>A layer should depend only on one direct layer (one level) beneath it, it shouldn’t know any layers beyond that level. For instance, Aon B ( A →B ), and B depends on C( B →C ), yet A shouldn’t know anything about C.</li><li>Each layer should depends upon abstraction ( interface ) rather than implementation. This complies with what Uncle Bob said about 2 rules to fix <strong>RFI</strong> issues, you can read it from my old blog <a href="https://yauritux.wordpress.com/2011/04/03/history-of-dependency-injection-di/">here</a>.</li></ul><p>Let’s start by looking on some DDD basic building blocks for our shopping cart as depicted above.</p><p>According to what i wrote <a href="https://blog.yauritux.link/ddd-part-ii-b0735ba584ca">here</a>, there are some technical building blocks within DDD, i.e. Entity, Value Object, Aggregate, Repository, and so forth. You can visit that link again to clarify the differences between all those things. Not all of those things are needed when we’re starting to implement our code, so just stick what we need based on the case (YAGNI).</p><p>First thing first, let’s create our project folder from the terminal and also initialize the go module as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PAHv2pNmfs-6tSuch8TfpA.png" /><figcaption>Initialize Project</figcaption></figure><p>Next step is by creating our pkg directory (mkdir pkg) from the same terminal. This pkg directory will contain our implementation logic for the shopping cart which complies with the clean code architecture we’re discussing here.</p><p>So here’s our project structure looks like for now:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/696/1*5IeLHOyZU0xj07WMnmgRXA.png" /><figcaption>Initial Project Structure</figcaption></figure><p>In terms of the clean code architecture, by referring to the depicted shopping cart process diagram, we’ll be having these following entities within our code:</p><ul><li><strong>User</strong> (this also represents a <strong>Buyer</strong> in theshopping cart bounded context, i.e. not all information need to be revealed here)</li><li><strong>Cart</strong></li><li><strong>Product</strong> (used as a placeholder for the product information. And for the sake of simplicity…, we won’t have any product categories because our goal here merely to discuss DDD with Clean Code Architecture).</li></ul><p>So, i create those 3entities within my pkg/domain/entity folder. To keep it simple, i have marked all of the fields as exported fields (later on, we can think about hiding the fields information behind the setter / getter which commons in Java).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6d9e5f443fc15dac636deb85164ed1a1/href">https://medium.com/media/6d9e5f443fc15dac636deb85164ed1a1/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b8017bfb57c3d6bb70378697e89db298/href">https://medium.com/media/b8017bfb57c3d6bb70378697e89db298/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/18f3dd0da6c857592842658223170728/href">https://medium.com/media/18f3dd0da6c857592842658223170728/href</a></iframe><p>And our value objects ( pkg/domain/valueobject ):</p><ul><li><strong>Cart Items</strong> (strongly related to product entity which the details information should be fetched from the product catalogue service, and this is beyond of what we’re discussing here).</li><li><strong>Buyer Address </strong>(comprises of Billing and Shipping addresses, determined by the Address Type)</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cdbf9543a7cc55dbc9bd456164c2667c/href">https://medium.com/media/cdbf9543a7cc55dbc9bd456164c2667c/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/80addd546dae22afe7e78ced54cd9134/href">https://medium.com/media/80addd546dae22afe7e78ced54cd9134/href</a></iframe><p>And our enum objects under sharedkernel/enum directory as following:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb2e4fca64db63ab04b28d03ba19668a/href">https://medium.com/media/eb2e4fca64db63ab04b28d03ba19668a/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9e914ea8d7f834b69c2f3257af3bd917/href">https://medium.com/media/9e914ea8d7f834b69c2f3257af3bd917/href</a></iframe><p>If you’re wondering about what <strong>shared kernel</strong> is, you can read it from my first part <a href="https://blog.yauritux.link/ddd-part-i-introduction-cabab1d2e27d">here</a>.</p><p>The next important thing to do is to implement our core business logic (a.k.a. core domain in Onion Architecture). This is something that is related to the enterprise business rules out of the application service rule.</p><p>In order to implement this kinda thing, we need to setup our <strong>aggregate root</strong> (i call it as user_cart <strong>aggregate</strong>). Again, take a look at what i wrote <a href="https://blog.yauritux.link/ddd-part-ii-b0735ba584ca">here</a> if you’re still wondering what is the <strong>aggregate</strong> all about.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9ba4b7030087530679b6b3fde012b020/href">https://medium.com/media/9ba4b7030087530679b6b3fde012b020/href</a></iframe><p>Another to-do thing is to setup our <strong>repositories</strong>. Bear in mind, that when we’re talking about <em>repository</em>, it’s not always about the <strong>database</strong>. The storage implementation could be anything such as: <strong>web services</strong>, <strong>file</strong>, <strong>in-memory</strong>, etc.., and they should be abstracted by following some contracts defined on the interface. In that way, we can use them interchangeably later since we make our client code depends on the interface rather than directly on the implementation. In order to make it possible, we should start by abstracting our repositories with interfaces such as following:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ca37d28299a04631ee273e8ce82305a/href">https://medium.com/media/1ca37d28299a04631ee273e8ce82305a/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e8d2055bb1f4f70d3c9554f32ca7b63f/href">https://medium.com/media/e8d2055bb1f4f70d3c9554f32ca7b63f/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/063fefe97fd5937db7f987dc248fa450/href">https://medium.com/media/063fefe97fd5937db7f987dc248fa450/href</a></iframe><p>I would assume that some of you will be asking me about those empty interfaces :-). Why do they exist ? Why do we use them ?.</p><p>As far as i concern, we’ll be having different models for every layer in order to make our architecture more loosely-coupled. In that case, we should abstract our interface model as far as we can, thus we can have more flexibility within our code. Let’s say for the user repository interface, we can have 2 implementations for it, one implementation to get the user information from the database, and another one to get the information from a web service (e.g. REST). Therefore, definitely we’ll have 2 models here, one based on the database model, and another one is based on the web response model. That’s the reason why we use empty interface ( interface{}) within our repository interface. You get it right ? :-). Don’t worry, everything will become clear once we implement our interface.</p><p>For the sake of simplicity, i’m going to implement <strong>in-memory repository</strong> for now since our first goal is merely to discuss about how’s our clean code architecture will be looked like. However, i will do as I can to incrementally update the code later for another storage / repository, such as <strong>database</strong> or <strong>web service</strong>. Feel free to <a href="https://github.com/yauritux">follow my account on GitHub</a> for this.</p><p>Let’s start to implement our repository interface by creating another directory (outside the domaindirectory, but still inside the pkg directory) as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4rtNbqMPF1gsh6OQIYqmhQ.png" /><figcaption>Setup the placeholder for In-Memory Repository Implementation</figcaption></figure><p>And here are our models (inside the pkg/adapter/repository/inmem/model directory) to be used in the context of our <strong>in-memory</strong> <strong>repository</strong> (remember about what i explained earlier about the interface{} ,when we designed our repository contract interface)</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4a88e4f09df4d627a31a27d496e9635d/href">https://medium.com/media/4a88e4f09df4d627a31a27d496e9635d/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fab28e6dae2b266d0201128e914c74e3/href">https://medium.com/media/fab28e6dae2b266d0201128e914c74e3/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b01127b5ff7ab1337c7970930a24c103/href">https://medium.com/media/b01127b5ff7ab1337c7970930a24c103/href</a></iframe><p>followed by our <strong>in-memory repository</strong> implementation for those 3 models respectively (inside. /adapter/repository/inmem directory):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/47e7620f0001dc6974968778020f6e50/href">https://medium.com/media/47e7620f0001dc6974968778020f6e50/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f06698a4ef79121e54b29cb0731e5025/href">https://medium.com/media/f06698a4ef79121e54b29cb0731e5025/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d82b0e3494f0bba683df6b2070bd2932/href">https://medium.com/media/d82b0e3494f0bba683df6b2070bd2932/href</a></iframe><p>And the <strong>use cases</strong> for the cart and user as written below :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4f1931d4b65afd10e559f4441df00444/href">https://medium.com/media/4f1931d4b65afd10e559f4441df00444/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c6fee3d99170463e3ff55b9d0fa8cf57/href">https://medium.com/media/c6fee3d99170463e3ff55b9d0fa8cf57/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fd6044e6dc002a8ef7026aceea7bd59/href">https://medium.com/media/2fd6044e6dc002a8ef7026aceea7bd59/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6f995a739e21e1c67d66442140a00d74/href">https://medium.com/media/6f995a739e21e1c67d66442140a00d74/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/18f91995bb6226591107ccbc597f56d5/href">https://medium.com/media/18f91995bb6226591107ccbc597f56d5/href</a></iframe><p>Last but not least, let’s create a small CLI program to test our shopping cart functionalities that we’ve created so far.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/38bae4eb0176d0d02d0d355cd0c7b7dd/href">https://medium.com/media/38bae4eb0176d0d02d0d355cd0c7b7dd/href</a></iframe><p>Ok, some of you might get overwhelmed with all of the code here (while some of you might not), especially in regards with the <em>use case</em> <em>port</em> and <em>interactor</em> (what would be the differences between those 2 ?). Hopefully it will be cleared soon.</p><p>Meanwhile, here’s our project structure looks like so far:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/620/1*mRy-mpcgXhdc2VJjyHd0bw.png" /><figcaption>Our Shopping Cart Service Project Structure with In-Memory Repository</figcaption></figure><p>And here’s when we’re running and testing our CLI program:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/798/1*Mvg0aSgiqGTxkYZK8EhNWg.png" /><figcaption>CLI Shopping Cart with In-Memory Repository</figcaption></figure><p>You can grab the full code <a href="https://github.com/yauritux/clean-code-architecture">here</a>. Again, feel free to <a href="https://github.com/yauritux">follow my GitHub account </a>so you won’t be missing any update that I made in the code :-).</p><p>Let me know for any concerns or questions from you folks :-). <br><a href="https://blog.yauritux.link/ddd-part-vi-ce543a0f1cbe">Read the next part here</a>.</p><blockquote><em>Any comments or suggests would be well appreciated.</em></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b0caf2437912" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My Journey with Python (Part I)]]></title>
            <link>https://yauritux.medium.com/my-journey-with-python-part-i-fdbc2609947c?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/fdbc2609947c</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python3]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Tue, 11 Jun 2019 05:13:17 GMT</pubDate>
            <atom:updated>2025-01-01T17:05:57.413Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*SXiCkfh0XRgPNVfOBboW3Q.png" /></figure><p>I’ve been working with <strong>Java</strong> for about 14 years now, and the last 2 years i’ve also worked with <strong>NodeJS</strong> and <strong>Golang</strong> to build some middleware AI platforms for my <a href="https://automate.id/">Startup</a>. Nevertheless, i often push myself in learning other technologies as well. I’ve been learning <strong>Python</strong> these past few weeks. I was inspired by its concise syntax and the prominent feature that supports almost anything. You can use <strong>Python</strong> for any GUI and/or web development, operating system shell, data processing and analysis (<em>data science</em>), etc. Someone said that you can build the world with <strong>Python</strong> :-). Mmmmm, sounds interesting.</p><p>Since i believe that the best way to grasp the knowledge is to write what i’ve learned, so i’m gonna try here to write everything i know so far about <strong>Python</strong>.<br>I have read from different books and websites, here i’m trying to summarize within 5 parts everything i got from those different resources. Hopefully, you would find this article useful, especially for those of you who’s trying to learn <strong>Python</strong> in a crash course.</p><p>As the title implied, this is the first part of my journey, and I’m thinking to write my journey within these following series:</p><ol><li>Python 3 Introduction → <em>you are here</em></li><li><a href="https://blog.yauritux.link/python-3-more-advanced-concepts-36b1094f32d6">Python 3 More Advanced Concepts</a></li><li>Develop your First Micro-service <em>(coming soon)</em></li><li>Python for Data Enthusiast <em>(coming soon)</em></li><li>Utilizing Generative AI (LLM) for building an AI-based Application <em>(coming soon)</em></li></ol><p>and each series contains several sections.</p><p>Please take a note that all of the aforementioned parts were designed to be barely enough for you to learn Python fast within few days or weeks and we’re targeting that once you reached the final parts, you’ll be able to build your AI-based application that utilizes GenAI (LLM) underneath :-).</p><h3>Python 3 Introduction</h3><p>This part will contain these following sections:</p><ol><li>What Python is and which version should i use ?</li><li>Installing Python</li><li>Package/Module (<em>dependency</em>) Management</li><li>What IDE (editor) to use</li><li>General Syntax and Semantics</li><li>IO Operation in Python</li><li>Package and Module System in Python</li><li>Best practice to start/manage your project</li><li>Sample Console App</li></ol><p>Enough the chit-chat and lets start with the first section :-).</p><h4><strong>What Python is and which version should i use ?</strong></h4><p>I won’t go details here since you can find many articles that explain about this. Shortly, i’d like to say that for those of you whom just started to learn python now (as i do), better to use Python 3 since it is the latest version and widely used now.</p><h4><strong>Installing Python</strong></h4><p>I believe that there are many resources out there to explain this installation process. So.. go ahead and grab it.</p><h4><strong>Package/Module (<em>dependency</em>) Management</strong></h4><p>Just like <strong>Java</strong>, <strong>Python</strong> also has <em>package/module manager</em> to <em>install/import </em>the <em>module</em> you need from the <em>online repository</em>. Even there are two tools you can use for this particular purpose (i.e. <strong>setuptools</strong> and <strong>pip</strong>), but I found that the easiest way to install the <em>module</em> you need was by using <strong>pip</strong> (i concluded that <strong>pip</strong> has superseded <strong>setuptools</strong>).</p><p>The <strong>pip</strong> is going to download the <em>package</em> from <a href="https://pypi.python.org/pypi"><strong>PyPI</strong></a> (<em>Python Package Index</em>), and then add it to your <strong>Python</strong> installation. From that point on, every <strong>Python</strong> script that you have on your system will have access to that particular package. Yet, please beware that different version can cause trouble to your application, especially if you have similar package (in different version) used within your different applications. For instance, lets say you have a complete web application using version 0.11 of Flask, and then you create another web application that is using version 0.12 of Flask. In this case, your second web application is running well, but unfortunately most likely it will break your older (first) application since it was expected to run with version 0.11 of Flask. You got the point right ? it would be ideal if you can install two different Flask versions for those two web applications respectively.</p><p>To address the issue of maintaining different versions of packages for different applications, <strong>Python</strong> has introduced the concept of <em>virtual environments</em>. <br>A <em>virtual environment</em> is a complete copy of the <strong>Python</strong> <em>interpreter</em>. When you install package in a <em>virtual environment</em>, the <em>global</em> (<em>system-wide</em>) <strong>Python</strong> <em>interpreter</em> is not affected, only the copy is. Therefore, the solution for you to have different package versions for different applications is by creating a different <em>virtual environment</em> for every application you have. <em>Virtual environments</em> also added the benefit that they are owned by the user who creates them, so they do not require an <em>administrator</em> account.</p><p>There are few ways to prepare your <em>virtual environment.</em> For me.. i used to prepare my virtual environment through these steps (all of the steps below were executed on the terminal) :</p><ol><li>Create your directory project and go into it.</li><li>Create the <em>virtual environment</em>: virtualenv -p python3 venv</li><li>Activate the virtual environment : source venv/bin/activate</li></ol><p>That’s all :-). For those of you whom still a bit confused, i captured my screen as depicted below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3FE8bepKC0M6iajHJz-0Kw.png" /><figcaption>How to prepare your Virtual Environment</figcaption></figure><p>There are something that i’d like to highlight here. First, venv is the newly created directory that contains your isolated python environment (yeap, you’re right… this is your new virtual environment, though you don’t have to named it venv. You can give it any arbitrary name). Second thing, if you get an unrecognized command when trying to execute virtualenv, that means you need to grab it first through this following command from within your terminal:</p><p>pip3 install virtualenv</p><h4>What IDE (editor) to use</h4><p>There are many options for this one, but i would recommend either <a href="https://code.visualstudio.com/">VisualStudio Code</a> or <a href="https://www.jetbrains.com/pycharm/">PyCharm</a>.</p><h4><strong>General Syntax and Semantics</strong></h4><p>Though you could find many resources about this one, but i’d like to recap some of those here. Hopefully, this will make you “dangerous enough” to start your journey as a Python developer after reading this blog series.</p><ul><li><strong>Basic Data Types</strong></li></ul><p>Python basic data types has nothing different with most basic data types in other programming languages. In general, you will find <strong>strings</strong>, <strong>numeric</strong>, and <strong>boolean</strong> values for <strong>Python Basic Data Types</strong>. Furthermore, numeric can be divided into an <strong>integer</strong> (int) and <strong>floating point</strong> (float). There is also complex data type (i.e. combination of real and imaginary numbers), but this kind of type is rarely used.</p><p>To define a string in Python, you can either surrounded it by using <em>single-quote</em> (’’) or <em>double-quotes</em> (””). Here’s the example:</p><pre>hero = &#39;Yauri Attamimi&#39;</pre><pre>msg = &quot;Yauri isn&#39;t coming today&quot;</pre><p>I’d like to explain few things here. First thing first, in order to define a variable in Python, you just need to specify a variable name (e.g. hero and msg) followed by an assignment operator (=) and the content/value of the variable.</p><p>Second thing regarding the above string definition, either way should be okay, yet sometimes it would depend on the content of your string value. For instance, in msg variable, we have enclosed the string value within the <em>double-quotes</em> (””) since the string’s content has a<em> single-quote</em> (’) in it.</p><p>Last but not least, important to know that Python is a <em>dynamic typed</em> (contrast with <em>strongly-typed</em> programming like Java), thus you can assign any arbitrary type to a variable. For instance, you can assign different types within one variable as you can see below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1004/1*uoaBjPgn6S1mwmN0uaHoww.png" /><figcaption>Python is Dynamic Typed</figcaption></figure><p>Shortly, other types can be explained below:</p><pre># an integer value<br>rank = 9 </pre><pre># a float value<br>fee = 7500.50</pre><pre># a boolean value (True | False) <br># note the uppercase letter! <br>is_success = True</pre><ul><li><strong>Operator</strong></li></ul><p>There are several basic operators in Python. I only show you here what are mostly used within your daily activities.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e730bbb9493d40d38e5cad2818adde78/href">https://medium.com/media/e730bbb9493d40d38e5cad2818adde78/href</a></iframe><ul><li><strong>Composite Data Types</strong></li></ul><p>Python has 3 mostly used <strong>composite data types</strong> as described below:</p><pre>&quot;&quot;&quot; List &quot;&quot;&quot;<br>members = [&quot;Yauri&quot;, &quot;Azizi&quot;, &quot;Fadzlan&quot;]</pre><pre>&quot;&quot;&quot; Tuple &quot;&quot;&quot;<br>members = (&quot;Yauri&quot;, &quot;Azizi&quot;, &quot;Fadzlan&quot;)</pre><pre>&quot;&quot;&quot; Dictionary &quot;&quot;&quot;<br>{<br>   &quot;id&quot;: 1,<br>   &quot;name&quot;: &quot;Yauri Attamimi&quot;,<br>}</pre><pre>&quot;&quot;&quot; Combination of List and Dictionary &quot;&quot;&quot;<br>members = [<br>   {&quot;id&quot;: 1, &quot;name&quot;: &quot;Yauri Attamimi&quot; }, <br>   {&quot;id&quot;: 2, &quot;name&quot;: &quot;Azizi&quot;}, <br>   {&quot;id&quot;: 3, &quot;name&quot;: &quot;Fadzlan&quot;}<br>]</pre><p>What make it <em>different</em> between <strong>list</strong> and <strong>tuple</strong> is that <strong>tuple</strong> is <em>read-only</em> (you can’t change once you created it), while <strong>list</strong> is <em>writable</em> thus you can modify the <strong>list</strong> with its <em>built-in</em> methods. Here’s the example:</p><pre># Define and yield a new list of members <br>members = [&quot;Yauri&quot;, &quot;Azizi&quot;, &quot;Fadzlan&quot;]<br>print(members)</pre><pre># append a new member into members, then yield<br>members.append(&quot;Joe&quot;)<br>print(members)</pre><pre># remove a member from the list<br>members.remove(&quot;Joe&quot;)</pre><p>You could find other list built-in methods from the <a href="https://docs.python.org/3/tutorial/datastructures.html">Python 3 official documentation</a>.</p><ul><li><strong>Iteration</strong></li></ul><p>There are 2 types of <strong>iteration</strong> in Python 3: while loop and forloop as described below:</p><pre># While Loop<br>x = 1<br>sum = 0<br>while x &lt;= 10:<br>   sum += x<br>   x += 1</pre><pre>print(f&#39;sum = {sum}&#39;) </pre><p>as you can see, initially we defined a variable x with value 1, then we iterate through the while statement with condition x &lt;= 10(i.e. the block statement inside a while will be executing repeatedly as long as the value of x is less than or equal to 10, thus you must not forget to increment the x value at the end of while block statement or else it will be looping forever). One important thing here as you might noticed already, In Python… instead of defining a block statement inside a curly braces ( { }) like in other programming languages (e.g. Java, C, etc), Python prefers to has an indentation over curly braces. That’s why you need to explicitly give an indentation to every statements that you’d like to put inside a block statement as shown above.</p><pre># For Loop<br>sum = 0<br>for x in range(1, 10):<br>    sum += x</pre><pre>print(f&#39;sum = {sum}&#39;)</pre><p>for statement in Python differs from what you might used in other programming languages like Java. Python’s for statement iterates over the items of any sequence (a <strong>list</strong> or a <strong>string</strong>). Do you read it ? yes, a <strong>string</strong>. You can also iterates over a <strong>string</strong> or <strong>list</strong> like these:</p><pre># Iterates over a list<br>members = [&quot;Yauri&quot;, &quot;Wu Ji&quot;, &quot;Oyama&quot;]<br>for name in members:<br>   print(name)</pre><pre># Iterates over a string<br>greetings = &quot;Good Morning&quot;<br>for item in greetings:<br>   print(item)</pre><ul><li><strong>Conditional Statements</strong></li></ul><p>Perhaps, the most well-known and widely used for this kind of statement is the if statement as shown below:</p><pre># if statement<br>greeting = &quot;Good Morning&quot;<br>if is_morning:<br>   print(greeting)</pre><pre># if else statement<br>if is_morning:<br>   print(greeting)<br>else<br>   print(&quot;Have a good day for you!&quot;)</pre><pre># if else if statement<br>if is_morning:<br>   print(greeting)<br>elif not is_morning:<br>   print(&quot;Have a good day for you!&quot;)<br>else:<br>   print(&quot;I don&#39;t know what to say...&quot;)</pre><ul><li><strong>Function</strong></li></ul><p>I believe that most of you know about <strong>function</strong>. Just to recap again, <strong>function</strong> is a block of statements (organized code) that is reusable, and is often used to perform a single action (it better be !).</p><blockquote>Function provides better modularity of your application !!</blockquote><p>Here’s how to define and calling functions:</p><pre>def calculate_order(total_cost, shipping_cost):<br>    return total_cost + shipping_cost</pre><pre><br>def print_total_order(): <br>    # call calculate_order function <br>    total_order = calculate_order(2000, 75) <br>    # print the result to console<br>    print(f&#39;Your total order: {total_order}&#39;)</pre><pre><br># call print_total_order function<br>print_total_order()</pre><p>As you see, you define a function by using keyword def. And the function body is written within a block statement (i.e. indicated by an indentation).</p><p>The <em>naming convention</em> used for a “function name” in Python is similar with the <em>naming convention</em> for a “variable name”, i.e. all written in lowercase, separated with an underscore (_)if has more than one word.</p><ul><li><strong>Exception</strong></li></ul><p><strong>Exception</strong> is a way to catch any error thrown from your program. Your program might be syntactically correct, but sometimes error might happen within your program. Consider the following code snippet:</p><pre>x = 2 / a<br>print(x)</pre><p>if you run that code, and somehow a is equal to zero (0), then you’ll obviously get the following error:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/546/1*2CvLA39K59KZ3GaMCEJRng.png" /></figure><p>and most of the case, the program will unexpectedly stop to run (<em>crash</em>).</p><p>In order to address that kind of situation, you’ll need to wrap those line of codes (which potentially cause an error) inside a try..exceptblock as shown below:</p><pre>try:<br>   x = 5 / 0<br>except ZeroDivisionError:<br>   print(&#39;cannot divide a number with zero!&#39;)<br>else:<br>   print(x)</pre><p>So if you run the program again, it will nicely print a friendly message as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/586/1*KQoZ12Le4MDtc0LHQrTR8w.png" /></figure><p>and the program will still continue running. Everyone is happy :-).</p><h4>IO Operation in Python</h4><p>There are many IO operations in Python, yet I will merely discuss here about input operation in the context of get an input from console and print an output to console, since this is what we need for our last section when we discuss about our console app application.</p><p>Read my short explanation below as usual (example of code):</p><pre># get a string input from a keyboard (within terminal)<br>name = input(&quot;Enter your name: &quot;)</pre><pre># print to console (terminal)<br>print(f&quot;Howdy {name} !&quot;)</pre><p>One important thing here, every input will be treated as a string by default, hence if you’d like to dealing with it in another data type such as an integer, you’ll need to cast the type as shown below:</p><pre># get an integer input from a keyboard (within terminal)<br>level = int(input(&quot;Enter your game level: &quot;))</pre><pre># print to console (terminal)<br>print(f&quot;Game Level: {level}&quot;)</pre><h4>Package and Module System in Python</h4><p>In <strong>Python</strong>, a <em>sub-directory</em> that includes a <strong>__init__.py</strong> file is considered as a package and can be imported. The <strong>__init__.py</strong> file is used to define what symbols are exposed by the package to the outside world. So when you import a package, the <em>python interpreter</em> will try to find and execute the <strong>__init__.py</strong> implicitly.</p><p>Here’s how to define a package (named <strong>utils</strong>):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/692/1*HQNQd9scmqw7Zmz-QyRMdw.png" /></figure><p>as depicted on the above image, we also created file <strong>converter.py</strong> inside our new <strong>utils</strong> package. Here’s the source:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ffb3357e44f729ff316221d5efa6233e/href">https://medium.com/media/ffb3357e44f729ff316221d5efa6233e/href</a></iframe><p>And here’s the various ways that can be used to import that particular package (hopefully quite explanatory for you ^_^):</p><pre># First Technique <br>from utils import converter</pre><pre><br>print(converter.lbs_to_kg(165)) <br>print(converter.kg_to_lbs(71.5))</pre><pre># Second Technique<br>from utils.converter import lbs_to_kg, kg_to_lbs</pre><pre><br>print(lbs_to_kg(165))<br>print(kg_to_lbs(71.5))</pre><pre># Third Technique<br>from utils.converter import lbs_to_kg as ptkg<br>from utils.converter import kg_to_lbs as kgtp</pre><pre><br>print(ptkg(165))<br>print(kgtp(71.5))</pre><h4><strong>Best practice to start/manage your project</strong></h4><p>There are several best practices to maintain your project. First and foremost… as discussed previously in the point number three (<strong>package/module management</strong>), the best way to start your project is by creating a <em>virtual environment</em> for it, thus you’ll have a freedom to manage your package versions without affecting your <em>global</em> <strong>Python’s</strong> <em>interpreter</em>.</p><p>As you can see, you can use virtualenv <em>command</em> to create the <em>virtual environment</em> from within your project folder. <br>And since Python 3, there is a <em>built-in virtual environment</em> included. Thus, instead of using virtualenvcommand as shown above, you can also use this following command:</p><p>python3 -m venv myfirstp3env</p><p>Regardless of the method you used to create it from those aforementioned commands, you will have a <em>virtual environment</em> inside your project folder, which is represented as a folder with the name you’ve choosen before (i.e. <strong>venv</strong> in this case) where the virtual environment files are stored.</p><p>Note that in some operating systems you may need to use python instead of python3 in the command above. Some installations use python for Python 2.x releases and python3 for the 3.x releases, while others map python to the 3.x releases.</p><p>Once you have your virtual environment within the project, don’t forget to tell the system that you’re going to use it by activating it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/604/1*9-sPeWGRlyVml9mu0no3mA.png" /><figcaption>Activate the Virtual Environment</figcaption></figure><p>When you activate a <em>virtual environment</em>, the configuration of your terminal session is modified so that the <strong>Python</strong> <em>interpreter</em> stored inside the <em>virtual environment</em> is the one that is invoked when you type python. The terminal prompt is also modified to include the name of the <em>activated</em> <em>virtual environment</em>, i.e. (venv) p3journey1in this case. Note that all changes made to your terminal session are temporary and private to that session, so it won’t persist when you close the terminal.</p><p>After created the <em>virtual environment</em> for your project, the next point is to ensure that you manage your project <em>source files</em> in term of <strong>packages</strong>. So, the application will exist in a <strong>package</strong>. (See point number 6, <strong>Module System in Python</strong>).</p><p>Last but not least, if you were using other external libraries (other than <em>built-in</em> libraries from Python), don’t forget to <strong>freeze</strong> your libraries by using this following command:</p><pre>pip freeze &gt; requirements.txt</pre><p>This will be listing all of your dependency libraries (incl. the version) within <strong>requirements.txt</strong> file. Consider this file same as a <strong>package.json</strong> (in NodeJS) or <strong>pom.xml </strong>(in Maven).</p><p>And don’t forget to skip/ignore your virtual environment folder from your repository. You can add/configure it by adding the folder name (<strong>venv</strong> in our case) into our <strong>.gitignore</strong> file (if you’re using <strong>Git</strong>).</p><p>That’s all of the best practices i found useful, at least for now :-).</p><h4>Sample Console App</h4><p>For our basic sample app, we’ll be creating a simple console application that asking a user to enter some basic informations such as their first name, last name, and weight (kgs or lbs). Subsequently, the console will display a healthy menu (including price) and asking you to choose which menu you’d like to order. Finally, the program will proceed to checkout order and asking you to pay some amount (the total cost will be displayed on the screen).</p><p>You can grab the sample code <a href="https://github.com/yauritux/p3journey1">here</a>.</p><p>That’s all for now, hope you like it and wait for the next part when we’ll be discussing about more advanced topics such as OOP in Python, Logging, Decorator, Generator, and some Python 3 distinctive features. Stay tuned :-)</p><blockquote>Any comments or suggests would be well appreciated.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fdbc2609947c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DDD Part IV]]></title>
            <link>https://yauritux.medium.com/ddd-part-iv-94a8c88504c0?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/94a8c88504c0</guid>
            <category><![CDATA[domain-driven-design]]></category>
            <category><![CDATA[software-design]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[microservices]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Fri, 29 Dec 2017 16:57:57 GMT</pubDate>
            <atom:updated>2024-05-06T16:49:09.576Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>DDD and Microservices</strong></p><blockquote>(originally published on <a href="https://dzone.com/articles/ddd-part-iv-ddd-amp-microservices">Dzone</a>)</blockquote><p>Finally, I got a chance to write the fourth part! For those of you who didn’t get the chance to read the previous parts, you can read them by starting on Part 1 <a href="https://blog.yauritux.link/ddd-part-i-introduction-cabab1d2e27d">here</a>.</p><p>Now.. within this part, I will try to elaborate on the <strong>microservices architecture</strong> and its relationship with <strong>Domain Driven Design</strong> (DDD).</p><h3>Microservices Architecture</h3><p>First things first: let’s describe what <strong>microservices architecture</strong> is all about.</p><p><strong>Microservices architecture</strong> is a kind of an architectural pattern that focuses on developing/building small, reusable, and scalable services. Microservices allow us to break our large system into a number of independent collaborating processes, thus it can help to avoid a big monolith application, which is difficult to maintain, especially if you have big projects with a big team.</p><p>Microservices also can be very useful when you have to create services for polyglot devices such as wearables, Internet of Things (IoT), mobile, desktop, and web.</p><p>Microservices itself is not a new term. It was coined in 2005 by Dr. Peter Rodgers, who mentioned micro web services based on SOAP. It has become more popular since 2010.</p><p>The keys to <strong>microservices architecture</strong> are:</p><ol><li>It is independently deployable in terms of stack, framework, and/or languages used.</li><li>It is deployed as a small service that keeps focusing on doing one thing well, i.e. domain-driven services.</li><li>Well-defined interfaces and minimal functionality.</li><li>Avoiding cascading failures and synchronous calls — reactive designing for failure.</li><li>Every service has its own data and uses events/messages to communicate with other services.</li><li>Every service is deployed independently and isolated from other services (usually running in its own container) and automatically scalable.</li></ol><p>The main goal is to provide you with a small set of independent services which run independently in different environments, but can communicate with each other (tight cohesion). As we know, coupling is a two-headed beast. On one side, tightly-coupled code is difficult to test, difficult to maintain/reuse, and typically exhibits “whack-a-mole” bug behavior (i.e. fixing one bug most likely will produce one or more new bugs). On the other side, a certain amount of coupling is also necessary since completely uncoupled code doesn’t do anything; thus, coupling is necessary but should be carefully managed. This is what we call “Loosely Coupled, Highly/Tightly Cohesive.”</p><h3>Microservices Benefits</h3><ol><li>Easy to scale as individual components.</li><li>Easy to deploy and reduce time deployment, i.e. you can deploy each module without interrupting any other module.</li><li>Easy to maintain due to its smaller code size, and you can have a small, focused team.</li></ol><h3>Microservices Challenges</h3><ol><li>It’s difficult to achieve strong consistency in distributed services.</li><li>It’s harder to debug and trace issues compared to monolithic applications.</li></ol><p>There are many other challenges that you will know yourself later, once you implement microservices. Nevertheless, it will depend on how you design and manage your microservices by following some well-known best practices, like API Management, Traffic Management, Services Monitoring, etc. I’ll try to encapsulate them later in another series, if I get the chance.</p><h3>How Does DDD Relate to Microservices?</h3><p>As mentioned earlier, in microservices, we build each service to serve only one thing and do one thing well. Each service is also isolated from the others. On this matter, DDD principles can help us to keep the scope of the service small through what it calls “bounded context.”</p><p>Subsequently, DDD is going to help you investigate and know your domain and all subdomains well through the communication you build with the domain experts. By knowing your domain and subdomains well, you will know the map contexts and how all subdomains interact with each other, which will help you in designing and choosing the type of your microservices architecture and what kind of approaches you use to implement them, whether a reactive approach, orchestration approach, or hybrid… it will depend on your knowledge about the domain you’re working on. There are pros and cons for each approach that need to be evaluated based on the project and your domain knowledge. DDD will help you make a decision on this matter.</p><p>That’s all for now… please let me know if you have any more insight into how DDD relates to microservices!</p><p>Read the next part <a href="https://blog.yauritux.link/ddd-part-5-b0caf2437912">here</a>.</p><blockquote>Any comments or suggests would be well appreciated.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=94a8c88504c0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DDD Part III]]></title>
            <link>https://yauritux.medium.com/ddd-part-iii-a4ef18ef9e03?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/a4ef18ef9e03</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[onionarchitecture]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Wed, 24 May 2017 14:55:24 GMT</pubDate>
            <atom:updated>2024-05-06T16:47:47.354Z</atom:updated>
            <content:encoded><![CDATA[<h4>DDD and Onion Architecture</h4><p>This is the third part of my DDD series. I encourage you to read the <a href="https://blog.yauritux.link/ddd-part-i-introduction-cabab1d2e27d">first</a> part and <a href="https://blog.yauritux.link/ddd-part-ii-b0735ba584ca">second</a> part before going further on this particular part.</p><p>Within this particular part, i’ll be talking about one of my favorite architecture called “Onion Architecture”. Nevertheless, allow me to recap first about what do we have so far about DDD as following:</p><blockquote>DDD is all about how we design our software from the business perspective, not from the technical perspective. For that purpose, we must go together with the domain expert (a.k.a business expert) during the design process, thus we can keep align with the business want. The process always start with what we call as ubiquitous language (i.e. we need to have standard term to be used along with the design and implementation process). Subsequently, break the complex domain into smaller sub-domain known as bounded context and carefully define the boundaries and contract used to communicate between the individual bounded context. So each bounded context appears as a black box to another (only care about the contract interface, no need to care about the implementation details since its hidden from the outside).</blockquote><blockquote>Additionally, there are some pitfalls that need to be avoided during the design and implementation. Those are data centric mindset when modeling the problem domain, focusing on implementation details such as entities, repositories, etc instead of the core concepts, generic and specific technical terms, and focus on DB transactions instead of business transactions.</blockquote><p>Ok, let’s start with the main topic now, shall we :-).</p><p><strong>Onion Architecture</strong> was coined by <em>Jeffrey Palermo</em>. If you ever heard about <strong>Hexagonal Architecture</strong> (a.k.a. <strong>Port and Adapters</strong>) from <em>Alistair</em> <em>Cockburn</em>, the idea of <strong>Onion Architecture</strong> actually was inspired from this <strong>Hexagonal Architecture</strong>. Whether it’s Onion, Hexagonal, or Clean-Code… they are similar in my opinion. What make them different were just the nomenclature and/or number of layers applied while you’re writing your code.</p><p>You don’t have to use <strong>Onion Architecture</strong> though you implement DDD. And you aren’t forced to use DDD as well in order to apply <strong>Onion Architecture</strong>. Both are independent each other. Therefore, you are free to use other than <strong>Onion Architecture</strong> for DDD (even traditional architecture such as MVC still fit in DDD). However, <strong>Onion Architecture</strong> is a strong candidate and suited for DDD.</p><p>What make <strong>Onion Architecture</strong> different with the Traditional one ? Lets see the traditional first and come up with <strong>Onion</strong> later.</p><p>In the traditional architecture, the application’s structure is comprises of three tier/layer such as depicted below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UaQCS-D27FGeHCBg32kg-Q.png" /><figcaption><strong>Traditional MVC Architecture</strong></figcaption></figure><p>As we can see, on this particular architecture each layer highly depends on the layers beneath it, and every layers normally will also dependent to some common infrastructures (e.g. frameworks or utility services). With this kind of architecture, it will be difficult to give a separation of concerns because of the created coupling between each layer (each layer is coupled to the layers below it, and each layer often coupled to various infrastructure concerns). Yeah, coupling is important in order to create the interaction between components in our system, but what i’m trying to say here is that this particular architecture creates unnecessary coupling.</p><p>For instance, let’s say the team had decided to use <a href="https://projects.spring.io/spring-boot/">SpringBoot</a> to build their microservices which represent the infrastructure layer. Subsequently, after couple years the team has decided to change the framework to another or perhaps just drop the SpringBoot. With this kind of architecture, it will be difficult to deploy the new framework without any adjustment (changes) in the other layers since each layer is highly coupled to the framework (infrastructure) layer. Thus, there will be a possibility for the team in breaking the current business layer which contains all of the business logic (business domain). Bear in mind that, a good system should have criteria MECE (Mutually Exclusive Comprehensively Exhaustive) a.k.a. “loosely coupled, highly cohesive”. Therefore, the more coupling you created in your system, there will be more effort you need to change the system and breaking it to small independent parts.</p><p>On the other side, the biggest offender (and most common) is the coupling of UI and business logic to the data access. Transitive dependencies are still dependencies. The UI won’t work if the business logic isn’t there, same as the business logic won’t work if the data access isn’t there. Data access changes frequently, and whenever the data access changed, you will also need to adjust / change the business layer with this particular architecture. And, did i mention before ? Changing the business layer which contains the business rule will have a big risk for the company, especially when the business already stable and the current system has widely used by the users in the Company.</p><p>Here’s why <strong>Onion Architecture</strong> come to the rescue :-). Take a look at the diagram below for the <strong>Onion Architecture</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/501/1*drTjp611ohgutDGTqf5BBQ.png" /><figcaption><strong>Onion Architecture</strong></figcaption></figure><p>There are lot aspects of <strong>Onion Architecture</strong>, but the main goal is how it controls the coupling. The basic rule that you need to bear in your mind is all coupling is toward the center. For instance in the depicted diagram we can say as follow:</p><ol><li>The “Infrastructure” layer will know about the “Application Services”, “Domain Services”, and “Domain Model”.</li><li>The “Application Services” will know about the “Domain Services” and “Domain Model”.</li><li>The “Domain Services” only know about the “Domain Model”.</li><li>The “Domain Model” only know about itself.</li><li>The inner layer will not and should not know about the outer layer. Hence, the “Domain Model” doesn’t know about “Domain Services”, “Application Services”, and “Infrastructure” layer. Same as the “Domain Services” doesn’t know about the “Application Services” and “Infrastructure” layer, and so forth.</li></ol><p>In the very center, we see the “Domain Model” which represents the state and behavior of the model for the Organization/Company (i.e. the application we’re trying to build). Around the domain model are other layers with more behavior where the number of the layers can be vary (i.e. no restriction of the number of the layers).</p><p>“Application Core” will glue all the layers like “Domain Model”, “Domain Services”, and “Application Services” (again, the numbers of the layers can be vary which means we can have more layers rather than just those 3 layers).</p><p>“Domain Model” is the very center, and since all coupling is toward the center, then the “Domain Model” must be coupled only to itself as mentioned before. Typically, the “Domain Model” consists collection of interfaces called <em>Repository Interfaces</em> those provide saving and retrieving mechanism for objects in the system. Thus, i can say that the “Domain Model” defines the contract of the object’s system behavior especially for saving and retrieving mechanisms. Remember, only the interfaces (not the implementation). We can leave the implementation later on different layers (i.e. the infrastructure layer).</p><p>The outer layer (i.e. “Infrastructure” layer) is reserved for things that frequently changed. These things should be isolated from the “Application Core”. UI, Automation Test, DatabaseAccess, NetworkAccess, FileAccess belongs to this “Infrastructure” layer.</p><p>That’s all folks. <a href="https://blog.yauritux.link/ddd-part-iv-94a8c88504c0">Read the next part here</a>.</p><blockquote>Any comments or suggests would be well appreciated.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a4ef18ef9e03" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DDD Part II]]></title>
            <link>https://yauritux.medium.com/ddd-part-ii-b0735ba584ca?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/b0735ba584ca</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[microservices]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Thu, 20 Oct 2016 17:30:36 GMT</pubDate>
            <atom:updated>2024-05-06T16:46:04.187Z</atom:updated>
            <content:encoded><![CDATA[<h4>DDD Building Blocks</h4><p>It’s been a while since i wrote the <a href="https://blog.yauritux.link/ddd-part-i-introduction-cabab1d2e27d">first part</a> of DDD series. Within this second part, i will continue with one of the most important thing of DDD before you’re going further with the implementation. First thing first, you must know about DDD building blocks as you can see below:</p><ol><li>Entities</li><li>Value Objects</li><li>Aggregate Roots</li><li>Repositories</li><li>Factories</li><li>Services</li></ol><p>Tighten your “seatbelt” :-). We’re going through the details of those aforementioned blocks now.</p><h3><strong>1. Entities</strong></h3><p>Entities (or “entity” in singular form) is a plain object that has an identity (ID) and potentially mutable. Each entity is uniquely identified by an ID rather than by an attribute, therefore two entities can be considered as equal (<em>identifier equality</em>) if both of them have the same ID, even though they have different attributes. This means the state of the entity can be changed anytime, but as long as two entities have the same ID, both are considered as equal regardless what attributes they have.</p><h3><strong>2. Value Objects</strong></h3><p>Value Objects are immutable. They have no identity (ID) like we found in Entity. <br>Two value objects can be considered as equal if both of them have the same type and the same attributes (applied to all of its attributes). <br>They are often uses for a thing like message passing and in fact they are particularly useful in the <em>API layer</em> within some layered architectures like <strong>Onion, Hexagonal, </strong>or<strong> Clean-Code Architecture </strong>to expose your domain concepts without necessarily expose the immutable aspect.</p><p>Some benefits of ValueObjects:<br>1. Compound of ValueObjects can swallow lots of computational complexity.<br>2. Entities can be released from logic complexity.<br>3. Improve extensibility, especially for testability and concurrency issues if using correctly.</p><h3>3. Aggregate Roots</h3><p>Aggregate root is an entity that binds together with other entities. Moreover, aggregate root is actually a part of aggregate (<em>collection/cluster of associated objects that treated as a single unit for the purpose of data changes</em>). Thus, each <em>aggregate</em> actually consists of an <em>aggregate root</em> and a <em>boundary</em>. For example, the relationship between <strong>Order</strong> and <strong>OrderLineItem</strong> within <strong>SalesOrder</strong> <em>domain</em> can be considered as an <em>aggregate</em> where <strong>Order</strong> acts as the <em>aggregate Root</em>, while the <strong>OrderLineItem</strong> is the child of <strong>Order </strong>within <strong>SalesOrder</strong> boundary.<br>One of the key features of an aggregate root is the external objects are not allowed to holds a reference to an aggregate root child entities. Thus if you need access to one of the aggregate root child entities (a.k.a aggregate), then you must go through the aggregate root (i.e. you can’t access the child directly).<br>The other thing is all operations in general within the domain should where possible go through an aggregate root. Factories, Repositories, and Services are some exceptions to this, but whenever possible, if you can create or require that an operation go through the aggregate root, that’s going to be better.</p><h3>4. Repositories</h3><p>Repositories are mostly used to deal with the storage. They are actually one of the most important concepts on the DDD because they have abstracted away a lot of the storage concerns (i.e. some form / mechanism of storage). <br>The repository implementation could be a file-based storage, or database (SQL / NoSQL based), or any other thing that is related with storage mechanism such as caching. Any combination of those are also possible. <br>Repository should not be confused with the data store. A repository job is to store aggregate roots. Underneath that, repositories implementation may actually have to talk to multiple different storage locations in order to construct the aggregates. Thus, a single aggregate root might be drawn from a REST API, as well as a database or files. You may wrap those in something called the data store, but the repository is sort of a further layer of an abstraction on top of all those individual data stores. Usually, i implement the repository as an <strong>interface</strong> within the <em>domain</em>/<em>domain services</em> layer within <strong>Onion</strong>-like <strong>Architecture</strong> (skip for now, gonna talk about this kind-of layered architecture later), and then the <em>implementation logic</em> of the <strong>repository interface</strong> is going to be defined in the <em>infrastructure</em> layer.</p><h3>5. Factories</h3><p>The factories are used to give an abstraction to the object construction (see <a href="http://www.oodesign.com/factory-pattern.html">Factory design pattern from GOF</a>). <br>A factory can also potentially return an aggregate root or an entity or perhaps a value object. <br>Often times, when you need a factory method for an aggregate root, it will be rolled in to the repository. So your repository might have a finder create method on it.<br>Usually factory also implemented as an <strong>interface</strong> within the <em>domain</em>/<em>domain</em> <em>services</em> layer with the implementation logic defined in the <em>infrastructure </em>layer.</p><h3>6. Services</h3><p>A service is basically exist to provide a home for operations that don’t quite fit into an aggregate root. As an example, when you have an operation that you don’t know on which aggregate root it goes into, perhaps it operates on multiple aggregate roots or maybe it doesn’t belong to any existing aggregate root, then you can put the logic into a service. However, don’t be rush to put everything into a service. First and foremost, its better to carefully analyze whether the operation fits into one of the existing aggregate root or not. If you couldn’t find the aggregate root, subsequently better to ask your self in case you have missed one aggregate root or perhaps there are domain concepts that you haven’t considered that should be brought into your domain before you put the operation into a service.</p><h3>Other Important Things</h3><p>I often found that many developers use term VO (Value Objects) and DTO (Data Transfer Object) interchangeably. They consider both are just to be the same. This is quite annoying for me. In that case, i’d like to clarify here that both are refers to different things. <br>As depicted on the picture below, VO and DTO are subset of a POJO/POCO. Entity is also a subset of POJO/POCO.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-PJWpAFq29uDEqJt0zMrDQ.png" /></figure><p>In the above depiction, POJO and POCO can be interchangeably used. Both are refer to the similar thing. Both are just domain object that mostly represent the domain / business object within the business application.</p><p>The term POJO (Plain Old Java Object) was coined by Martin Fowler and very popular in Java community, while POCO (Plain Old CLR Object / Plain Old Class Object) is widely used in the dotNet.</p><p>As mentioned earlier, DTO, VO, and Entity are just a subset of POJO/POCO. However they are really different things as described below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gLLWywd76Tg_poJ0aiWalg.png" /></figure><p>DTO is merely a stupid data container (only holds data without any logic). Thus, its anemic in general (only contains attributes and getter/setter). DTO is absolutely immutable. Usually we use DTO to transfer the object between layers and tiers in one single application or between application to application, or JVM to JVM (mostly useful between networks to reduce multiple network call).</p><p>VO is also immutable, but what make it different with DTO is that VO also contains logic.</p><p>That’s all for now. Read the next part <a href="https://blog.yauritux.link/ddd-part-iii-a4ef18ef9e03">here</a>.</p><blockquote>Any comments or suggests would be well appreciated.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b0735ba584ca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[DDD Part I]]></title>
            <link>https://yauritux.medium.com/ddd-part-i-introduction-cabab1d2e27d?source=rss-fa3ab82e4f38------2</link>
            <guid isPermaLink="false">https://medium.com/p/cabab1d2e27d</guid>
            <category><![CDATA[event-sourcing]]></category>
            <category><![CDATA[cqrs]]></category>
            <category><![CDATA[eventstore]]></category>
            <category><![CDATA[command-query-separation]]></category>
            <category><![CDATA[domain-driven-design]]></category>
            <dc:creator><![CDATA[M Yauri M Attamimi]]></dc:creator>
            <pubDate>Thu, 29 Sep 2016 04:07:03 GMT</pubDate>
            <atom:updated>2024-05-06T16:45:00.242Z</atom:updated>
            <content:encoded><![CDATA[<h4>Introduction</h4><blockquote>(also published on <a href="https://dzone.com/articles/ddd-part-i-introduction">https://dzone.com/articles/ddd-part-i-introduction</a>)</blockquote><p>The first time I heard about DDD (stands for <strong>Domain Driven Design</strong>, not D̶e̶a̶d̶l̶i̶n̶e̶ ̶D̶r̶i̶v̶e̶n̶ ̶D̶e̶s̶i̶g̶n̶ forsure), i was still working as a Senior Java Developer for Hewlett-Packard on its Development Center at Cyberjaya, Malaysia. I wasn’t quite interested with the topic since it was difficult to get a good resource during that time. Someone told me to find the Eric Evan’s book (“the blue book”), and gotcha..i got the book and added it to my PDF collection.</p><p>During this time, DDD is quite new (especially in Indonesia), thus only few companies have successfully implemented this new thing. And somehow IMO, i found that many DDD resources were too difficult to be grasped by most of the readers (i.e. they are too abstract and lack of good examples). Therefore, i’m planning to pick up this awesome topic and write it in a series, equipped with an application sample to be followed step by step.</p><p>This is the first part of other series as follow:</p><ol><li><em>DDD Part I, Introduction → You are here</em></li><li><a href="https://blog.yauritux.link/ddd-part-ii-b0735ba584ca">DDD Part II, DDD Building Blocks</a></li><li><a href="https://blog.yauritux.link/ddd-part-iii-a4ef18ef9e03">DDD Part III, DDD and Onion Architecture</a></li><li><a href="https://blog.yauritux.link/ddd-part-iv-94a8c88504c0">DDD Part IV, DDD and Microservices</a></li><li><a href="https://blog.yauritux.link/ddd-part-5-b0caf2437912">DDD Part V, Code Implementation</a></li><li><a href="https://blog.yauritux.link/ddd-part-vi-ce543a0f1cbe">DDD Part VI, ES and CQRS Implementation</a></li></ol><p>In this first part of Introduction, i would like to start with some basic concepts as written below:</p><ol><li>What is DDD all about ?</li><li>How do we get started ?</li><li>What should we avoid in DDD ?</li></ol><p>Let’s get started :-).</p><h3>1. What is DDD all about ?</h3><p>To start this section, I’d rather took the definition from one of <a href="https://dddcommunity.org/">DDD community</a>, that describes DDD (Domain Driven Design) as an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts.<br>As the definition implies, DDD is suitable for you if you’re building a software that has complexity on its business process (business domain). So, not every software is suitable for DDD (e.g.: a simple CRUD application doesn’t suitable for it since it’s not that complex).<br>Eventually, team work is very important within DDD since you need to keep in touch with the users/clients (a.k.a Domain Experts). Moreover, you build the software for them, not for you (you got the point right). Just like someone said: “the software can fail either in two ways, you build the things wrong or you build the wrong things”. In that case, you have to ensure that you understand correctly the business that you’re going to build. This is DDD all about.<br>To summarize, DDD can be described as a technique for developing software that focuses on collaboration between technical experts and domain experts. Therefore, we must keep focus with the domain experts instead of the nitty gritty details of the technical stuffs.</p><h3>2. How do we get started ?</h3><p>First thing first, as mentioned earlier, the big point is to keep in touch with the <strong>business</strong>/<strong>domain expert</strong>.</p><p>Following, i had recap several points those we can use as the <em>guidance</em> while we have discussion with the <strong>domain expert</strong>:</p><ol><li>Learning about the <em>problem domain</em>, i.e. the specific problem the software you’re working on is trying to solve. Look at the big picture of the current business process.</li><li>Breaking the <em>domain</em> into smaller <em>sub-domains.</em></li><li>Focusing on one <em>sub-domain</em> at a time with the <strong>domain expert</strong>, and always use <a href="http://martinfowler.com/bliki/UbiquitousLanguage.html">ubiquitous language</a> to define working out terminology.</li><li>Creating a <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a> between <em>sub-domain</em> (again, <a href="http://martinfowler.com/bliki/UbiquitousLanguage.html">ubiquitous language</a> should always be used throughout the <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a>, from conversations to code, in the diagram, on the whiteboard, in the design document, team discussion, etc. The point is to use the <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a> everywhere).</li><li>Ideally, there will be different team, codebase, and database for each <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a>.</li><li>Since everyone are working for their <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a>, so they are free to change anything within their <em>context</em>.</li><li>For all <em>cross cutting concerns</em> those are shared between <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a> (we call it <strong>shared kernel</strong>), any changes should be known and agreed between all team in every <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a>.</li><li>Always stay focus with the domain’s <em>behaviors</em> rather than domain’s <em>state</em> (favor <a href="http://www.slideshare.net/chris.e.richardson/building-rich-domain-models">rich model</a> over <a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html">anemic model</a>).</li></ol><p>To summarize, always use <a href="http://martinfowler.com/bliki/UbiquitousLanguage.html">ubiquitous language</a> (i.e. same terminology) across the team, break the <em>domain</em> into smaller <em>subdomains</em> and give an isolation (i.e. <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a>) by defining the boundary and think about how the <em>subdomain</em> within the <a href="http://martinfowler.com/bliki/BoundedContext.html">bounded context</a> can communicate to each other using <strong>interfaces</strong> / <strong>crafted software contract</strong>.</p><h3>3. What should we avoid in DDD ?</h3><p>On the other hand, during our DDD implementation, we need to be careful for certain practices those are too common among software developers. These are :</p><ul><li>Using data centric view when modeling the problem domain.</li></ul><blockquote>Usually data model is the first thing that an architect/developer would start to design. They always consider that data is the most important thing because data is all what we need to report. If you start with DDD, you must change this mindset. Data on its own is meaningless. <strong>Only logic gives data a meaning !!!</strong>, and <strong>the same data can have different meaning in different contexts</strong>. Therefore, we must start with <strong>context</strong> and <strong>logic</strong> instead of data.</blockquote><ul><li>Focusing on implementation details like entities, value objects, services, factories, repositories, etc instead on the core concepts as discussed earlier.</li></ul><blockquote><strong>Entities</strong>, <strong>value objects</strong>, <strong>repositories</strong>, and so forth don’t have a meaning until we defined the <strong>ubiquitous language</strong>, <strong>bounded contexts</strong>, and the <strong>interfaces</strong> / <strong>crafted software contract</strong>. If we start to early with the implementation details like entities, then it’s a good chance that the result would be an anemic domain surrounded by a lot of services and business logic scattered everywhere.</blockquote><ul><li>Using generic and developer specific terms and concepts when implementing the application.</li></ul><blockquote>We should never use concepts like save, update, delete, handle, manage, etc. Those concepts are too technical or abstract concepts with no specific meaning. Instead, we must stay focus with the business concepts. Those aforementioned concepts (i.e. save, update, etc) are not related to business concepts. To understand this, i encourage myself to always imagine the client run his errands/business without computers (i.e. doing specific task manually). So, always think from the business/domain expert perspective, and give a clear context on it. Avoid generic term that can lead to different meaning in different context (i.e. use specific context).</blockquote><ul><li>Finally overrating DB transactions instead of focusing on the business processes or transactions.</li></ul><blockquote>Within DDD, business transactions is more important than DB transactions. DB transaction is <strong><em>ACID</em></strong>, <strong><em>strongly consistent</em></strong>, and <strong><em>short running</em></strong>, while business transaction is not. In fact, in the real life, we don’t know about DB transaction, we just know about business transaction. For example, imagine when you sit in the restaurant and order some foods and/or beverages. Within the order transaction, realize it or not, there will be a process with some asynchronous tasks with many possible inconsistent state changes, even by the end all states will be consistent (<strong><em>eventually consistent</em></strong>). And this blackbox process is works, scalable and widely acceptable by everyone.</blockquote><blockquote>Therefore with DDD, do not ever think about DB transactions, instead always think about the real world process such as what the possible actions (behaviors), and their possible outcome or about how to compensate the actions if some failures occurred.</blockquote><p>You don’t have to understand all the aforementioned points for now. I know that most application developers not too familiar with the idioms and peculiarities of those concepts. Just keep reading for now, and hopefully they will become clear when the other parts coming.</p><p>Read the next part <a href="https://blog.yauritux.link/ddd-part-ii-b0735ba584ca">here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cabab1d2e27d" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>