{"componentChunkName":"component---src-components-blog-template-js","path":"/blog/2023-05-14-clean-architecture/","result":{"data":{"markdownRemark":{"frontmatter":{"title":"Clean Architecture","date":"2023-05-14"},"html":"<p>As projects grow bigger, the code tends to get messy if there is no clear structure. I have worked on projects where everything was mixed together, and making a small change in one place would break something completely unrelated. Clean architecture is an approach to organising code so that each part has a clear responsibility and changes in one area do not ripple through the entire codebase.</p>\n<h3>Separation of Concerns</h3>\n<p>The core idea is to separate the code into layers, where each layer has a specific job. A common way to organise this is:</p>\n<p><strong>Presentation layer</strong> handles the UI. In a React app, this would be the components, pages, and anything related to what the user sees and interacts with.</p>\n<p><strong>Business logic layer</strong> contains the rules and logic of the application. For example, how to calculate a discount, what conditions must be met before placing an order, or how to validate user input beyond simple format checking.</p>\n<p><strong>Data layer</strong> handles communication with external sources like APIs, databases, or local storage. This includes the fetch calls, data transformations, and error handling for external requests.</p>\n<h3>Why It Matters</h3>\n<p>When these layers are mixed together, we end up with components that fetch data, apply business rules, and render the UI all in one place. This makes the component hard to test because we cannot test the business logic without rendering the UI. It also makes it hard to reuse the logic because it is tied to a specific component.</p>\n<p>By separating them, we can test the business logic independently, reuse it across different components, and swap out the data source without touching the rest of the code.</p>\n<h3>Practical Example</h3>\n<p>Instead of putting everything in a React component:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">function OrderPage() {\n  const [orders, setOrders] = useState([]);\n  \n  useEffect(() => {\n    fetch(\"/api/orders\")\n      .then(res => res.json())\n      .then(data => {\n        const filtered = data.filter(o => o.status !== \"cancelled\");\n        const sorted = filtered.sort((a, b) => b.total - a.total);\n        setOrders(sorted);\n      });\n  }, []);\n  \n  return &lt;OrderList orders={orders} />;\n}</code></pre></div>\n<p>We can separate it:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">// data layer\nfunction fetchOrders() {\n  return fetch(\"/api/orders\").then(res => res.json());\n}\n\n// business logic\nfunction getActiveOrdersByTotal(orders) {\n  return orders\n    .filter(o => o.status !== \"cancelled\")\n    .sort((a, b) => b.total - a.total);\n}\n\n// presentation\nfunction OrderPage() {\n  const [orders, setOrders] = useState([]);\n  \n  useEffect(() => {\n    fetchOrders().then(data => {\n      setOrders(getActiveOrdersByTotal(data));\n    });\n  }, []);\n  \n  return &lt;OrderList orders={orders} />;\n}</code></pre></div>\n<p>The component is now simpler. The fetch logic and business logic can be tested on their own. If the API endpoint changes, we only update the data layer. If the filtering rules change, we only update the business logic.</p>\n<h3>Folder Structure</h3>\n<p>A simple folder structure that reflects this separation could look like:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">src/\n  components/\n  pages/\n  services/\n  utils/\n  hooks/</code></pre></div>\n<p><code class=\"language-text\">services</code> for the data layer, <code class=\"language-text\">utils</code> for shared business logic, <code class=\"language-text\">hooks</code> for reusable stateful logic, and <code class=\"language-text\">components</code> and <code class=\"language-text\">pages</code> for the presentation layer. The exact structure depends on the project size, but the principle stays the same: keep each layer in its own place.</p>"}},"pageContext":{"slug":"/2023-05-14-clean-architecture/"}},"staticQueryHashes":[]}