Skip to main content

Що таке "Layered Architecture" у фронтенді?

Що таке 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
UIModelDomainData
  • 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 - це "архітектурний скелет" застосунку: кожен шар знає своє місце і не втручається в чужі справи.

Це робить код зрозумілим, тестованим і стійким до росту проєкту.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.