<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gulshan</title>
    <description>The latest articles on DEV Community by Gulshan (@gulshan).</description>
    <link>https://dev.to/gulshan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F83830%2F835e36a5-f6ad-4671-804d-e345db8dc36d.png</url>
      <title>DEV Community: Gulshan</title>
      <link>https://dev.to/gulshan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gulshan"/>
    <language>en</language>
    <item>
      <title>Where is my "Business logic"!?</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Sat, 18 May 2024 19:02:29 +0000</pubDate>
      <link>https://dev.to/gulshan/where-is-my-business-logic-5gpn</link>
      <guid>https://dev.to/gulshan/where-is-my-business-logic-5gpn</guid>
      <description>&lt;p&gt;It's common to hear you should separate your "business logic". There are numerous articles emphasizing the importance of this separation. And then there are a lot of suggestions showing the structure of a project with this separation of "Business logic" or "Domain logic". But I used to have a basic problem while trying the separation. The problem is- what are the things I should consider as "Business logic"? Where is it? Then I came up to a very simple answer- "separate the I/O".&lt;/p&gt;

&lt;p&gt;So, imagine in the software, existing or proposed, all the I/O has been taken care of. So, reading/decoding/parsing/encoding/writing is not your problem. All you are left with the data, in the structure you intended. So, you have to-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate the input.&lt;/li&gt;
&lt;li&gt;Do the whatever you want to do with it.&lt;/li&gt;
&lt;li&gt;Return the output.
And if you then write your program with only these concerns, Voilà! You got your "Business logic" or "Domain logic"!!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, the things left to do are doing the technical part. Here you take the input, decode it, parse it, (de)serialize it into the structure defined by your domain logic layer and then send it to them. Then receive the outcome, serialize it, encode it and show/send as output. Your program is run by this technical part, but it always follows the business logic.&lt;/p&gt;

&lt;p&gt;Then there is another point to keep in mind. There can be internal and external, inputs and outputs. The external input is the one you are getting from the "Request" of a user or external service. And then you may require some more input from your database, which is the internal input. And after processing, you may save some updates to the data in your database and send some data in the response, which are internal and external outputs, respectively. So, the "business logic" layer should take these two types of inputs separately and return the two types of output separately.&lt;/p&gt;

&lt;p&gt;The "technical" layer of the program should handle reading/writing all these inputs and outputs. In most of the time, the internal/DB input is dependent on the external input. And the external input should be validated before retrieving the internal input. You may even want to apply some kind of business logic "before" retrieving the internal input. So, the internal/DB input should not be passed as direct data to the business logic layer. Rather, you should pass a lambda/delegate to the business layer, which can be used by the business layer to retrieve the internal/DB inputs. In this way, the business logic layer will be indifferent to the way the internal/DB data is being retrieved, but still can control whether it should be used or not.&lt;/p&gt;

&lt;p&gt;For the internal/DB output, the business layer does not need to know how the data is being saved. It should just mark the data which should be saved. Again, the structure of the different types of input and output data is being defined by the business logic layer and the technical layer would just follow it. Any error in the serialization/deserialization is the concern of the technical layer.&lt;/p&gt;

&lt;p&gt;Another point to keep in mind is the "mutations". All the changes (create/update/delete operations) in the internal/DB data should happen in the business layer. The technical layer will be "saving" the change, but "making" the change is responsibility of the business layer.&lt;/p&gt;

&lt;p&gt;Sometimes it may seem the business layer is doing very little or nothing at all. It may raise the question that is it worth the trouble separating this little part to a totally separate layer? The answer is, yes it will be totally worth it, especially in the long term.&lt;/p&gt;

&lt;p&gt;And this separation of business layer has another benefit, now you can easily do the unit testing. Basically, you have to write unit tests for all the cases of business logic layer. And if you have separated the business logic from the I/O, you most probably would not need any "mocking".&lt;/p&gt;

&lt;p&gt;In ideal cases, you should be able to rewrite or refactor your technical layer without touching the business layer. Same goes for the storage engine, user interfaces, the device of the user etc. And in the longer term, this is definitely going to happen. Happy coding!&lt;/p&gt;

</description>
      <category>businesslogic</category>
      <category>domainlogic</category>
      <category>architecture</category>
    </item>
    <item>
      <title>When to catch an Exception?</title>
      <dc:creator>Gulshan</dc:creator>
      <pubDate>Sun, 10 Sep 2023 10:45:43 +0000</pubDate>
      <link>https://dev.to/gulshan/when-to-catch-an-exception-51i0</link>
      <guid>https://dev.to/gulshan/when-to-catch-an-exception-51i0</guid>
      <description>&lt;p&gt;When developing with a common programming language like Java, C# or likewise, I have faced a dilemma when calling a function/method which may throw exceptions. What should I do about these exceptions? Should I catch them, or let them flow? If I catch them, what should I do with the caught exceptions? Just log them? How much should the &lt;code&gt;try&lt;/code&gt; block encompass? Only that very function call or the full workflow? So many decisions to make regarding those exceptions! After a bit of soul-searching, I came up with a few rules of mine to handle the exceptions.&lt;/p&gt;

&lt;p&gt;Most probably the function/method in question is expected to return some kind of value/object, which will be used for further processing. And an exception means the expected return path was not followed and thus the current workflow cannot continue. Now, if you want to &lt;strong&gt;continue&lt;/strong&gt; despite the exception, you can encompass that one function call to catch the exception and then do one of the following:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continue with a default value:&lt;/strong&gt; In this case, the exception was somewhat expected, and you use a default value and continue the workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry:&lt;/strong&gt; This is a common scenario for an operation involving network calls. There can be some issue with the network. So, on a network related exception, you can wait a few milliseconds and try the call again, maybe for some "n" times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try another way:&lt;/strong&gt; It's like one network call fails, then you try to get the value in some other way like proxy or reading from a file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Or&lt;/strong&gt; some combination of above three.&lt;/p&gt;

&lt;p&gt;And if you do not actually wish to continue the workflow on an exception, it would be better &lt;strong&gt;not&lt;/strong&gt; to encompass only that function-call with try-catch, and then forcefully return/return &lt;code&gt;null&lt;/code&gt;/assign &lt;code&gt;null&lt;/code&gt; to the receiving object. Just let the exception flow in its destined error path and keep the "Happy path" of your code clean.&lt;/p&gt;

&lt;p&gt;Okay, what about logging? Yes, all the exceptions should be logged/recorded. If possible, an "Application monitoring" service/tool should be used to record the exceptions, so that they can be analyzed later. But to log or record an exception, you have to catch the exception, right? When should you catch for logging/recording?&lt;/p&gt;

&lt;p&gt;IMHO, catching the exceptions to record them should happen at the &lt;strong&gt;root&lt;/strong&gt; of a workflow, generically, for all exceptions. This is like catching just before the crash. If your application has well defined workflows, like web applications, the framework or some application monitoring tools may take care of this automatically for you.&lt;/p&gt;

&lt;p&gt;Here, by &lt;strong&gt;"workflow"&lt;/strong&gt; I mean a set of operations performed together, which also "fails together". In a web application, handling a request can be considered as a workflow. An application may have one or more parallel or sequential workflows. Failure in one workflow should not affect others. That's why the logging/recording/handling/consumption of the exception should be done at the root of a workflow.&lt;/p&gt;

&lt;p&gt;Sometimes, you may want to put some extra information while logging a specific exception, which is not in it. This information can be a message, custom filter, tag etc. Instead of logging it with the specific information, you can catch an exception, put the information within the exception, and then rethrow it. .net has the &lt;code&gt;Data&lt;/code&gt; property in the Exceptions for this purpose, Java has a &lt;code&gt;setData&lt;/code&gt; method. When this exception will be caught and recorded at the root of the workflow, the custom information should also be recorded with it.&lt;/p&gt;

&lt;p&gt;Another thing to keep in mind is that, when an exception is handled at the root of a workflow, the handling is generic for all exceptions. But when handling and exception in other places, like shown above, it should be specific to certain types of exceptions only. A common way to check if some function is the root of a workflow is to see if some other function depends on it. If not, then this is a root of some workflow.&lt;/p&gt;

&lt;p&gt;Hope this helps. Happy coding.&lt;/p&gt;

</description>
      <category>exceptions</category>
      <category>exceptionhandling</category>
    </item>
  </channel>
</rss>
