<?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>Forem: Hossein Molaei</title>
    <description>The latest articles on Forem by Hossein Molaei (@hosseinmolaei).</description>
    <link>https://forem.com/hosseinmolaei</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%2F3199184%2F27cdd681-a445-49bd-802a-722e6ac3fb44.jpg</url>
      <title>Forem: Hossein Molaei</title>
      <link>https://forem.com/hosseinmolaei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hosseinmolaei"/>
    <language>en</language>
    <item>
      <title>🧱 Open/Closed Principle — One of Uncle Bob’s Fundamental Architectural Rules</title>
      <dc:creator>Hossein Molaei</dc:creator>
      <pubDate>Thu, 05 Jun 2025 11:19:37 +0000</pubDate>
      <link>https://forem.com/hosseinmolaei/openclosed-principle-one-of-uncle-bobs-fundamental-architectural-rules-1mg0</link>
      <guid>https://forem.com/hosseinmolaei/openclosed-principle-one-of-uncle-bobs-fundamental-architectural-rules-1mg0</guid>
      <description>&lt;p&gt;Continuing with the SOLID principles, today we will come to these two principles. To understand my point of view, you can read the Single Responsibility Principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📌 What Is the Open/Closed Principle?&lt;/strong&gt;&lt;br&gt;
The Open/Closed Principle, introduced by Bertrand Meyer in Object-Oriented Software Construction (1988), is defined as follows:&lt;/p&gt;

&lt;p&gt;“A software artifact should be open for extension but closed for modification.”&lt;/p&gt;

&lt;p&gt;This means a software component should allow new features to be added without modifying existing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❓ What Does That Actually Mean in Software?&lt;/strong&gt;&lt;br&gt;
Most developers understand and apply this principle at the level of a single class or service. That’s not necessarily wrong — but that’s not true OCP either.&lt;/p&gt;

&lt;p&gt;To properly implement OCP, you must consider it at the architectural level, across your entire project, not just individual modules. This principle helps preserve the long-term structure of your system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧪 Let’s Imagine an Experiment&lt;/strong&gt;&lt;br&gt;
Imagine you’re showing a page of business reports to users. Now, the user wants to export the report in a nicely formatted Word or PDF file.&lt;/p&gt;

&lt;p&gt;Of course, we need to write new code — but here’s the real question:&lt;/p&gt;

&lt;p&gt;How much of the existing code do we need to modify?&lt;/p&gt;

&lt;p&gt;A well-designed software architecture aims to minimize code changes — ideally, none.&lt;/p&gt;

&lt;p&gt;However, we know that in about 80% of cases, OCP can be satisfied this way. But we must also respect the Single Responsibility Principle (SRP) when designing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34lpp03ctua559iuo8b8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34lpp03ctua559iuo8b8.png" alt="Image description" width="800" height="302"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;⚙️ Separation of Concerns: Logic vs. Presentation&lt;/strong&gt;&lt;br&gt;
After implementing the reporting system, you realize it has two main parts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculation&lt;/strong&gt;&lt;br&gt;
Presentation (output)&lt;br&gt;
Any future changes — like adding a new export format — should be made only in the Presentation part. Thanks to this separation, we are confident that changes in one responsibility do not affect the other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fons9jp5xop9enwfxaupc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fons9jp5xop9enwfxaupc.png" alt="Image description" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔄 Direction of Dependency and OCP&lt;br&gt;
Let’s say it again:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If Component A needs to be protected from changes in Component B, then B should depend on A, not the other way around.&lt;/p&gt;

&lt;p&gt;In our example, we want to protect the Controller from changes in the Presenter. Therefore, the Presenter should depend on the Controller — but the Controller must not know about the Presenter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎯 Why the Interactor Is an OCP Champion&lt;/strong&gt;&lt;br&gt;
The Interactor is in the best position regarding OCP. Why?&lt;/p&gt;

&lt;p&gt;It is not affected by changes in the Controller, Presenter, or even Database.&lt;br&gt;
It holds the core business logic and policies, and it’s not concerned with the implementation details of other components.&lt;br&gt;
If you’re still unclear, go back and look at the previous image again.&lt;br&gt;
We designed our system top-down and when we needed to add a new export format, we first respected SRP, and then applied OCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧩 Real-World Conflict: When OCP Is Broken&lt;/strong&gt;&lt;br&gt;
Let’s be careful:&lt;/p&gt;

&lt;p&gt;Even though we can add new capabilities to the Interactor, if that involves changing its interface, then the Controller must change too.&lt;br&gt;
👉 That would violate OCP.&lt;/p&gt;

&lt;p&gt;However, if we only add code to the Controller, and the Interactor remains untouched, then we’ve fully respected OCP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Final Conclusion&lt;/strong&gt;&lt;br&gt;
We can conclude:&lt;/p&gt;

&lt;p&gt;Designing the system from large to small helps protect lower-level components from unnecessary changes.&lt;/p&gt;

&lt;p&gt;And in approximately 80% of use cases (this is an intuitive figure), OCP can be achieved.&lt;/p&gt;

&lt;p&gt;Whenever you manage to fully respect OCP, you’ve likely designed an ideal system.&lt;/p&gt;

&lt;p&gt;_Author: Hossein Molaei&lt;br&gt;
Translation from Persian to English by artificial intelligence&lt;/p&gt;

&lt;p&gt;ref: Clean Architecture (Robert C Martin)_&lt;/p&gt;

</description>
      <category>programming</category>
      <category>solidprinciples</category>
      <category>csharp</category>
      <category>robertcmartin</category>
    </item>
    <item>
      <title>SOLID Principles from the Perspective of Robert C. Martin</title>
      <dc:creator>Hossein Molaei</dc:creator>
      <pubDate>Mon, 26 May 2025 08:54:14 +0000</pubDate>
      <link>https://forem.com/hosseinmolaei/solid-principles-from-the-perspective-of-robert-c-martin-5cd7</link>
      <guid>https://forem.com/hosseinmolaei/solid-principles-from-the-perspective-of-robert-c-martin-5cd7</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;According to Uncle Bob, the Single Responsibility Principle (SRP) can only be applied correctly when you clearly identify the system’s actors.&lt;/p&gt;

&lt;p&gt;“A module should be responsible to one, and only one, actor.”&lt;/p&gt;

&lt;p&gt;Sometimes, the best way to prove a principle is to explore what happens when it’s violated.&lt;/p&gt;

&lt;p&gt;Let’s look at a common example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The calculatePay() method is defined and used by the Accounting department, which reports to the CFO.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The reportHours() method is used by HR, reporting to the COO.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The save() method is managed by DBAs, under the CTO.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w92phwih57le8be1gj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w92phwih57le8be1gj2.png" alt="Image description" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first glance, it might seem that the class follows SRP. After all, each method has a single job. But in reality, this is a clear violation of SRP. Why?&lt;/p&gt;

&lt;p&gt;Because placing these three methods in a single class connects three different actors — meaning changes from one team might affect the others unintentionally.&lt;/p&gt;

&lt;p&gt;⚠️&lt;strong&gt;A Real-World Scenario&lt;/strong&gt;&lt;br&gt;
Imagine both calculatePay() and reportHours() share a helper method called regularHours().&lt;/p&gt;

&lt;p&gt;This method might seem like a single responsibility function. But what happens if the accounting department wants to change how overtime is calculated? They modify regularHours() to meet their needs.&lt;/p&gt;

&lt;p&gt;But here’s the issue: HR is also using regularHours() — and they’re not aware of the change. The accounting team runs their tests and everything seems fine. But a few weeks later, HR starts complaining about inaccurate reports.&lt;/p&gt;

&lt;p&gt;By the time the issue is discovered, the organization may have already suffered from incorrect data and misinformed decisions.&lt;/p&gt;

&lt;p&gt;SRP tells us that this could’ve been avoided by separating responsibilities by actor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z1mh6jrzsy4xdc4p1dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z1mh6jrzsy4xdc4p1dg.png" alt="Image description" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👨‍💻 &lt;strong&gt;Parallel Development Chaos&lt;/strong&gt;&lt;br&gt;
Now imagine two developers working on this class:&lt;/p&gt;

&lt;p&gt;One updates calculatePay() for the finance team.&lt;br&gt;
The other updates reportHours() for HR.&lt;br&gt;
When it’s time to merge, they run into conflicts — despite modern version control tools being quite advanced, merge conflicts in shared classes are still risky and can introduce subtle bugs.&lt;/p&gt;

&lt;p&gt;✅** A Better Design**&lt;br&gt;
One practical solution is to separate data from behavior. Instead of one large Employee class, you split responsibilities:&lt;/p&gt;

&lt;p&gt;PayCalculator handles payroll logic.&lt;br&gt;
HoursReporter manages working hours.&lt;br&gt;
EmployeeRepository deals with persistence.&lt;br&gt;
All of these classes can access a shared EmployeeData structure — a plain data holder without any business logic.&lt;/p&gt;

&lt;p&gt;Each class contains only the source code necessary for its own responsibility. They are not aware of each other, reducing the chance of accidental overlap or unintended coupling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuu6t5nz4zyblm4mm9kx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuu6t5nz4zyblm4mm9kx.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Facade to the Rescue&lt;/strong&gt;&lt;br&gt;
You might object: “Now I have three classes to instantiate and track!”&lt;/p&gt;

&lt;p&gt;That’s fair. A common approach here is to use the Facade Pattern — a single class that hides the complexity of the subsystem and offers a simplified interface to the outside world.&lt;/p&gt;

&lt;p&gt;So your application deals with one class, but under the hood, responsibilities remain separated.&lt;/p&gt;

&lt;p&gt;🧠 &lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;br&gt;
The Single Responsibility Principle should be enforced not just at the method level, but throughout the entire architecture — from the top down.&lt;/p&gt;

&lt;p&gt;Every actor in the system should have a corresponding class, with focused methods that serve only that actor’s needs. This leads to a system that is easier to scale, test, and maintain.&lt;/p&gt;

&lt;p&gt;SRP isn't about writing fewer classes — it's about writing better ones.&lt;/p&gt;

&lt;p&gt;Taken from the book Clean Architecture by Robert C. Martin&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Translated by artificial intelligence from Persian to English.&lt;br&gt;
Author : Hossein Molaei&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
