Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке "Layered Architecture" у фронтенді?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Layered Architecture (багаторівнева архітектура)** - це принцип розділення застосунку на **шари**, де кожен шар має **свою зону відповідальності** і **обмежені залежності**. **Ключове:** кожен шар відповідає лише за один аспект системи і знає тільки про шари нижче, але не вище - напрямок залежностей завжди "вниз".Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке Layered Architecture > **Layered Architecture (багаторівнева архітектура)** - це принцип розділення застосунку на **шари**, > де кожен шар має **свою зону відповідальності** і **обмежені залежності**. Іншими словами: > Кожен шар відповідає **за один аспект системи**, > і знає **тільки про шари нижче**, але **не вище**. --- ## Навіщо потрібні шари Коли застосунок росте, логіка, дані та UI починають змішуватися. Шари дозволяють це структурувати: - кожен шар вирішує **своє завдання**, - взаємодія між шарами чітко визначена, - і код стає **передбачуваним і масштабованим**. --- ## Типові рівні (frontend-версія) | Шар | Зона відповідальності | Приклад | |---|---|---| | **UI / Presentation Layer** | Відображає дані користувачу | Компоненти React, форми, кнопки | | **State / Application Layer** | Керує станом застосунку і бізнес-правилами | Redux / Zustand / Hooks / Context | | **Domain Layer** | Зберігає бізнес-логіку і моделі предметної області | функції на кшталт `calculateDiscount()`, `UserEntity` | | **Data / Infrastructure Layer** | Працює із зовнішніми джерелами даних | REST, GraphQL, API-клієнти, LocalStorage | --- ## Приклад (React + API) ### Без шарів (все в одному компоненті) ```javascript function ProductList() { const [products, setProducts] = useState([]); useEffect(() => { fetch("/api/products") .then(res => res.json()) .then(setProducts); }, []); return ( <div> {products.map(p => ( <div key={p.id}>{p.name} - {p.price}$</div> ))} </div> ); } ``` > Тут компонент одночасно: > > - робить запит (data layer), > - керує станом (application layer), > - відображає UI (presentation layer). > > → Архітектурна "каша". --- ### З розділенням на шари ```javascript // data/productsApi.js export async function getProducts() { const res = await fetch("/api/products"); return res.json(); } // domain/productService.js export function calculateDiscount(product) { return product.price * 0.9; } // model/useProducts.js (application/state layer) import { useEffect, useState } from "react"; import { getProducts } from "../data/productsApi"; import { calculateDiscount } from "../domain/productService"; export function useProducts() { const [products, setProducts] = useState([]); useEffect(() => { getProducts().then(res => { setProducts(res.map(p => ({ ...p, discounted: calculateDiscount(p) }))); }); }, []); return products; } // ui/ProductList.jsx (presentation layer) import { useProducts } from "../model/useProducts"; export function ProductList() { const products = useProducts(); return ( <div> {products.map(p => ( <div key={p.id}> {p.name} - {p.discounted}$ </div> ))} </div> ); } ``` > Тепер кожен шар ізольований: > > - `data/` - відповідає за запити > - `domain/` - за бізнес-логіку > - `model/` - за стан > - `ui/` - за відображення --- ## Правила залежності шарів ```javascript UI → Model → Domain → Data ``` - **UI** знає про **Model**, але не про **Domain** напряму - **Model** може звертатися до **Domain** і **Data** - **Domain** - незалежний (не знає про UI чи API) - **Data** - найнижчий шар, обслуговує всіх > Напрямок залежностей завжди "вниз". --- ## Layered Architecture у Feature-Sliced Design У FSD (Feature-Sliced Design) цей принцип формалізовано у вигляді **шарів проєкту**: ```javascript shared/ ← (інфраструктура і спільні модулі) entities/ ← (доменні моделі) features/ ← (прикладні фічі) pages/ ← (збірка фіч у сторінки) processes/ ← (наскрізні сценарії) app/ ← (ініціалізація застосунку) ``` > Кожен шар залежить **тільки від нижчерозташованих** - > наприклад, `features` можуть використовувати `entities`, але не навпаки. --- ## Переваги Layered Architecture | Перевага | Опис | |---|---| | **Розділення відповідальності** | Кожен шар вирішує одне завдання | | **Ізоляція змін** | Можна змінювати шар, не ламаючи інші | | **Зрозуміла структура** | Проєкт легко читати і масштабувати | | **Тестованість** | Шари тестуються незалежно | | **Перевикористання** | Можна виносити бізнес-логіку в інші проєкти | | **Сумісність з DDD/FSD** | Легко інтегрується із сучасними архітектурними підходами | --- ## Layered vs Feature-Based Architecture | Підхід | Поділ за... | Приклад | |---|---|---| | **Layered Architecture** | Ролями (UI, Logic, Data) | `ui/`, `domain/`, `data/` | | **Feature-Based Architecture** | Функціональністю (auth, cart) | `features/auth/`, `features/cart/` | > Кращий варіант - **комбінувати обидва**: > всередині кожної **фічі** теж можна тримати **шари** (`ui/`, `model/`, `domain/`, `api/`). --- ## Підсумок | Що | Опис | |---|---| | Ідея | Ділити застосунок на логічні рівні з чіткими залежностями | | Основні шари | UI / Application / Domain / Data | | Напрямок залежностей | Тільки згори вниз | | Ціль | Структура, читабельність, масштабованість | | У React | Часто реалізується всередині фіч (через FSD або Clean Architecture) | --- > **Головна думка:** > Layered Architecture - це "архітектурний скелет" застосунку: > кожен шар знає своє місце і не втручається в чужі справи. > > Це робить код **зрозумілим, тестованим і стійким до росту проєкту**.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.