<?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 Giorgi Koguashvili on Medium]]></title>
        <description><![CDATA[Stories by Giorgi Koguashvili on Medium]]></description>
        <link>https://medium.com/@kogoia?source=rss-116d2ef735b5------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*F1Q8pzRWhscsPOPPGjbGAA.jpeg</url>
            <title>Stories by Giorgi Koguashvili on Medium</title>
            <link>https://medium.com/@kogoia?source=rss-116d2ef735b5------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 19:41:38 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@kogoia/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[Discriminated Unions for Designing Domain Models in C#]]></title>
            <link>https://kogoia.medium.com/discriminated-unions-for-designing-domain-models-in-c-1e54109adbdd?source=rss-116d2ef735b5------2</link>
            <guid isPermaLink="false">https://medium.com/p/1e54109adbdd</guid>
            <category><![CDATA[csharp]]></category>
            <category><![CDATA[algebraic-data-types]]></category>
            <category><![CDATA[fsharp]]></category>
            <category><![CDATA[discriminated-union]]></category>
            <dc:creator><![CDATA[Giorgi Koguashvili]]></dc:creator>
            <pubDate>Tue, 01 Aug 2017 14:21:04 GMT</pubDate>
            <atom:updated>2017-08-01T20:12:55.843Z</atom:updated>
            <content:encoded><![CDATA[<p>Domain model requires thorough designing in which are well suited <a href="https://en.wikipedia.org/wiki/Algebraic_data_type"><strong>ATD </strong></a>(Algebraic Data Type) such as <a href="https://en.wikipedia.org/wiki/Tagged_union"><strong>Sum Types</strong></a>, which name in computer science is <strong>Discriminated Unions</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/409/1*piuAZNTr_Fm3Z84SgKr7uw.jpeg" /><figcaption>Image taken from Bartosz Milewski’s <a href="https://bartoszmilewski.com/2015/01/13/simple-algebraic-data-types/">blog</a></figcaption></figure><p>Consider a simple example to make it more clear.</p><p>Imagine we have <strong>Contact </strong>class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/118c319f94b1b26ef3a49c9e540a7968/href">https://medium.com/media/118c319f94b1b26ef3a49c9e540a7968/href</a></iframe><p>These are all defined as simple strings, but really are they just strings? Of course not. The <strong>Name </strong>can consist of <strong>First Name</strong> and <strong>Last Name</strong>. Or is an Email just a set of symbols? I know that at least it should contain <strong>@ </strong>and it is necessarily.</p><p>Let’s improve us domain model:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/778fa2366e707ea4f6662e046dfb752d/href">https://medium.com/media/778fa2366e707ea4f6662e046dfb752d/href</a></iframe><p>In this classes will be validations during creating and we will eventually have valid models. Consturctor in <strong>PersonaName </strong>class require <strong>FirstName </strong>and <strong>LastName </strong>at the same time. This means that after the creation, it can not have invalid state.</p><p>And <strong>Contact </strong>class respectively:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b5ada5f236b4676b8e1d7495ddf0dc5e/href">https://medium.com/media/b5ada5f236b4676b8e1d7495ddf0dc5e/href</a></iframe><p>In this case we have same problem, object of <strong>Contact </strong>class may be in invalid state. I mean it may have <strong>EmailAddress </strong>but haven’t <strong>Name</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/23b519a24417898be746a86fb044ef88/href">https://medium.com/media/23b519a24417898be746a86fb044ef88/href</a></iframe><p>Let’s fix it and create <strong>Contact </strong>class with constructor which requires <strong>PersonalName</strong>, <strong>EmailAddress </strong>and <strong>PostalAddress</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/043c5448ecde1c3e43d0209497d8d590/href">https://medium.com/media/043c5448ecde1c3e43d0209497d8d590/href</a></iframe><p>But here we have another problem. What if <strong>Person </strong>have only <strong>EmailAdress </strong>and haven’t <strong>PostalAddress</strong>?</p><p>If we think about it there we realize that there are three possibilities of valid state of <strong>Contact </strong>class object:</p><ol><li>A contact only has an email address</li><li>A contact only has a postal address</li><li>A contact has both an email address and a postal address</li></ol><p>Let’s write out domain models. For the beginning we will create <strong>Contact Info </strong>class which state will be corresponding with above cases.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a5f3dcfc07961f527ba56d159de13f41/href">https://medium.com/media/a5f3dcfc07961f527ba56d159de13f41/href</a></iframe><p>And <strong>Contact </strong>class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e1772d99df61490b3093296f25e46d9d/href">https://medium.com/media/e1772d99df61490b3093296f25e46d9d/href</a></iframe><p>Let’s try use it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d3137a9e569b1bc45e5ee5401b0e1d3b/href">https://medium.com/media/d3137a9e569b1bc45e5ee5401b0e1d3b/href</a></iframe><p>Let’s add <strong>Match </strong>method in <strong>ContactInfo </strong>class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/141b43ccc5dd4d0965090118fa38ba10/href">https://medium.com/media/141b43ccc5dd4d0965090118fa38ba10/href</a></iframe><blockquote><em>In the match method, we can write this code, because the state of the contact class is controlled with constructors and it may have only one of the possible states.</em></blockquote><p>Let’s create an auxiliary class, so that each time do not write as many code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9cdab9300abb17b86a40df32781a7324/href">https://medium.com/media/9cdab9300abb17b86a40df32781a7324/href</a></iframe><blockquote><em>We can have such a class in advance for several types, as is done with delegates Func, Action. 4–6 generic type parameters will be in full for Union class.</em></blockquote><p>Let’s rewrite <strong>ContactInfo </strong>class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6a6314a51c00b50602586feac187f0a3/href">https://medium.com/media/6a6314a51c00b50602586feac187f0a3/href</a></iframe><blockquote><em>Here the compiler will ask override for at least one constructor. If we forget to override the rest of the constructors we can’t create object of ContactInfo class with another state. This will protect us from runtime exceptions during Matching.</em></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c0297932a92a6120cd1467feae17b7f2/href">https://medium.com/media/c0297932a92a6120cd1467feae17b7f2/href</a></iframe><p>That’s all. I hope you enjoyed.</p><p>Example taken from the site <a href="https://fsharpforfunandprofit.com/">F# for fun and profit</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1e54109adbdd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to avoid Null checks with LINQ?]]></title>
            <link>https://kogoia.medium.com/how-to-avoid-null-checks-with-linq-11ac4a6a43fb?source=rss-116d2ef735b5------2</link>
            <guid isPermaLink="false">https://medium.com/p/11ac4a6a43fb</guid>
            <category><![CDATA[linq]]></category>
            <category><![CDATA[monads]]></category>
            <category><![CDATA[functional]]></category>
            <category><![CDATA[maybe]]></category>
            <category><![CDATA[null]]></category>
            <dc:creator><![CDATA[Giorgi Koguashvili]]></dc:creator>
            <pubDate>Tue, 18 Jul 2017 07:33:55 GMT</pubDate>
            <atom:updated>2017-07-18T11:28:10.972Z</atom:updated>
            <content:encoded><![CDATA[<p>We are all familiar with LINQ, but we don’t quite reveal its power in our code. I’ll try to explain to you, one technique that I use in my projects on daily basis.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/300/1*fRhoO14ZjIpO_EC0-rowcw.png" /></figure><p>Imagine a typical situation, we have a method which gives Product by its Id, but if it is not found returns null:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6ba8649f02d8a141632fe99624bf3406/href">https://medium.com/media/6ba8649f02d8a141632fe99624bf3406/href</a></iframe><p>And the one who is going to call this method, should write code like this</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/33318fe12f01bed3065b5067e0452863/href">https://medium.com/media/33318fe12f01bed3065b5067e0452863/href</a></iframe><p>We can avoid this null check if we look at this problem from the other side.</p><blockquote>Why null is bad idea you can see in <a href="https://www.google.ru/?gws_rd=ssl#newwindow=1&amp;q=why+null+is+bad">many</a> of articles which gives google search results</blockquote><p>What if every time when we can’t find something we will return an empty <em>thing</em>, otherwise a <em>thing </em>with one element.</p><p>This example will help:</p><blockquote>Dear, bring me a glass of cold water, or if the water is hot then empty glass. And I will decide what to do with it.</blockquote><p>Helped?</p><p>Then an example of the code in here:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ce6e109f3a762736019e4148da892e7c/href">https://medium.com/media/ce6e109f3a762736019e4148da892e7c/href</a></iframe><p>Instead of <em>thing </em>we use <strong>List&lt;T&gt;</strong> and return empty list if we can’t find product or list with one element instead.</p><p>And code on the usage side:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/929c825924f5920dbd1e1f1630fe8f59/href">https://medium.com/media/929c825924f5920dbd1e1f1630fe8f59/href</a></iframe><p>Do you see a difference? I don’t.</p><p>But we can go further. For this we need another example.</p><p>What if after retrieving product, we want find details about it on Amazon?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a8f497c041daf5f81fb2f782bad9fd43/href">https://medium.com/media/a8f497c041daf5f81fb2f782bad9fd43/href</a></iframe><p>If we use the usual approach, then code will look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ec2a2975ce44b46a805c511d1eb19364/href">https://medium.com/media/ec2a2975ce44b46a805c511d1eb19364/href</a></iframe><p>But if we do not violate the agreement that was adopted above, that we always return <em>thing </em>with element, our code might look like this:</p><blockquote>.DetailsFromAmazon() also returns <strong>List&lt;ProductDetails&gt;</strong></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8678720271a88ad26f3afd9f968070b4/href">https://medium.com/media/8678720271a88ad26f3afd9f968070b4/href</a></iframe><blockquote>.SelectMany does very simple thing it flattens list of lists (two dimensional list) and returns one flat (one dimensional) list.</blockquote><pre>// [[1,2],[3,4,5]] - this is List of Lists<br>new List&lt;List&lt;int&gt;&gt;()<br>{<br>    new List&lt;int&gt;() { 1, 2 },<br>    new List&lt;int&gt;() { 3, 4, 5 }<br>}<br>.SelectMany(list =&gt; list); // [1, 2, 3, 4, 5] - this is flat list</pre><blockquote>More about .SelectMany you can see in Jon Skeet’s <a href="https://codeblog.jonskeet.uk/2010/12/27/reimplementing-linq-to-objects-part-9-selectmany/">post</a></blockquote><p>Here the benefits are already noticeable, we avoid one null check. Let’s go further, don’t stop.</p><p>We can write one small extension method for <strong>IEnumerable&lt;T&gt; </strong>with name <strong>Match</strong>, which takes two functions, look at the code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b7f3304a143022e47c58c8615341c907/href">https://medium.com/media/b7f3304a143022e47c58c8615341c907/href</a></iframe><p>And we can change code below on this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a17623eea0ea51bccf69594ab083a29a/href">https://medium.com/media/a17623eea0ea51bccf69594ab083a29a/href</a></iframe><p>That’s all.</p><p>In next article I will show what kind of helpers I use every day on projects at my job.</p><p>I hope you enjoyed. :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=11ac4a6a43fb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why do we still not know how to develop projects properly?]]></title>
            <link>https://kogoia.medium.com/why-we-still-do-not-know-how-to-properly-develop-projects-921a018aecf6?source=rss-116d2ef735b5------2</link>
            <guid isPermaLink="false">https://medium.com/p/921a018aecf6</guid>
            <category><![CDATA[scrum]]></category>
            <category><![CDATA[management]]></category>
            <category><![CDATA[xdsd]]></category>
            <category><![CDATA[project-development]]></category>
            <category><![CDATA[agile]]></category>
            <dc:creator><![CDATA[Giorgi Koguashvili]]></dc:creator>
            <pubDate>Mon, 17 Jul 2017 06:34:22 GMT</pubDate>
            <atom:updated>2020-12-10T06:16:11.664Z</atom:updated>
            <content:encoded><![CDATA[<p>Honestly, I do not know. But I think we are making one big mistake and I will try to explain it here.</p><p>Let’s talk about long-term projects that benefit the business and need to be developed and maintained. During this time, entire teams around the project may change, including management. This leads to the fact that the project becomes difficult to manage because knowledge of the project is partially lost or scattered over many people. Things get even worse when looking at the code left by developers who left the team. Even if the team does not change, it’s difficult for us to understand our own code. At best, this will lead to a rewrite of the project from scratch or the Customer deciding not to develop the project at all. It is not effective, looking at how much it costs. This, in turn, will also have an impact on business development. But let&#39;s leave the business to customers. To prevent this, we need to find a new approach to project development.</p><p>The biggest mistake is that we work together <strong>on a project</strong> instead of working together <strong>through the project</strong>. Sounds strange, yes? I will explain what I mean.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/531/1*OGQ2YspHm6wiEJiFybIoCw.png" /><figcaption>M — Manager, D — Developer, ⇔— Communication</figcaption></figure><p>This is how the traditional scheme of work looks like. And this at the best-case. The manager describes the customer requirements, wherever (e.g., Excel, Trello, Jira). Developers try to break them into tasks, communicating with each other through communication tools (e.g., Skype, Slack, Mail) and making meetings or phone calls with the manager. After this, developers write code based on accumulated knowledge during all this communication.</p><p>Notice, Manager gives Customer Requirements. It is a one-way direction, I mean, he doesn’t receive feedback in the same way, through Jira, Trello. This contributes to the loss of knowledge about the project because no one records meetings and phone conversations. I call this the leak of knowledge.</p><p>After one of the developers leaves the project, knowledge is lost because his decision is nowhere written.</p><p>At the end of the project, the customer receives the product as a hosted application and only source code, without any documentation and manual, about building and hosting the project or why we take these architectural decisions.</p><p>This will be a problem for another team that will continue developing the project and for us.</p><p>That’s what I mean by “working together <strong>on a project</strong>.” Let’s take a look at how the work looks <strong>through the project</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/416/1*fc_H8gyurWxUNWXsNTIw1Q.png" /><figcaption>M — Manager, D — Developer, ⇔ — Communication</figcaption></figure><p>In this case, we see that all communication between a team occurs through Tasks, which is in the same place as the code. (it can be Jira with Bitbucket where on Task we can attach code branch on which we work or GitHub with own Issues). Notice that the Manager, as a full member of the development team, participates in the division of Customer Requirements into tasks. The whole process of knowledge sharing is through Tasks and comments to him.</p><p>No piece of code should be written without a task. No more undescribed problems. All conversations and making decisions now are available to all through Tasks.</p><p>This is a good example of how Open Source projects develop.</p><p>In this post, I’m not going to disclose why this approach works better or how to organize processes to achieve this work style. All the answers to questions you find in <a href="http://www.yegor256.com/">Yegor Bugayenko</a> <a href="http://www.yegor256.com/tag/xdsd.html">posts</a>, and the author of the new software development methodology <a href="http://www.xdsd.org/">XDSD</a>. Thanks to him for this.</p><p>In short, we must keep our accumulated knowledge somewhere in an understandable form and have one source of knowledge about the project. That the project itself had value without us developers, I mean it must be self-describing and self-sufficient.</p><p>Probably you have already sighed. I apply this methodology to the project and solve all my problems. It won’t! Even if you implement this approach, one big problem remains. Even if you implement this approach, there remains a big problem.</p><p>Communication through Task is only 30–40% of all communication through the project. We, the programmers, mainly communicate through the code we write. I mean that every day we read code which is written by another developer (e.g., Unit Tests, Code Review), who outlined his thoughts about a task through a piece of code.</p><p>And if we do not improve the understandability and readability of the code, we will fall into a bottleneck, which depends on the project development velocity.</p><p>How to write good code; this is a topic for another article.</p><p>Also, if you noticed, I did not mention <a href="https://en.wikipedia.org/wiki/Agile_software_development"><strong>Agile</strong></a><strong> </strong>software development principles and <a href="https://en.wikipedia.org/wiki/Scrum_(software_development)"><strong>Scrum</strong></a><strong> </strong>as one of its realizations. Because there’s a lot written about Agile already and in Scrum, there is something, the lack of which saves us from many problems. I mean meetings. No more Scrum Master needed, which should protect developers from management, and many other side effects. It reminds me of a shepherd protects sheep from wolves :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=921a018aecf6" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>