5.8 KiB
5.8 KiB
UI Five-Layer Architecture Standard
Table of Contents
- Scope and Intent
- Core Model
- Layer Definitions
- UI Module Levels
- Dependency Rules
- Event Communication Rules
- Interaction Flow
- Naming and Folder Conventions
- Testing Policy
- Anti-Patterns
- Delivery Checklist
Scope and Intent
Use this standard to define and enforce a stable UI architecture that can be reused across projects.
Primary goals:
- keep business logic independent from UI rendering
- keep UI rendering deterministic and testable
- make reviews and refactors consistent
- reduce coupling and regression risk
Core Model
Base chain:
External Flow
-> Controller
-> UseCase
-> RawData / Result
-> BuildContext
-> View
View
--(UI-local event)--> Controller
Rules:
UseCaseproduces business outputs only.Controlleris the only layer that createsContext.Viewonly renders and emits interaction events.
Layer Definitions
UseCase
Responsibilities:
- own business rules and state transitions
- validate business actions
- return
RawDataor result objects
Constraints:
- do not depend on
Context,View, or rendering types - do not format display strings or map visual assets
- do not publish UI-local events
RawData
Responsibilities:
- carry business data from
UseCasetoController
Constraints:
- keep data business-oriented
- do not reference any
*Contexttype - do not contain rendering objects (for example UI components)
Controller
Responsibilities:
- be the external entry point for open/close/refresh
- bind and call
UseCase - transform
RawData/ResultintoContext - subscribe/unsubscribe UI-local events
- coordinate full or partial refresh
Constraints:
- do not let
Viewbypass controller orchestration - do not hide heavy business logic that belongs in
UseCase
Context
Responsibilities:
- carry display-ready data for rendering
Constraints:
- construct/update only in
Controller - do not enter
UseCase - allow composition (
FormContext,ItemContext,AreaContext)
View
Responsibilities:
- bind controls and render
Context - emit UI-local interaction events
Constraints:
- do not call
UseCase - do not mutate domain state
- do not subscribe to global business events
- do not become external entry points
UI Module Levels
Standard Five-Layer Module
Structure:
UseCase + RawData + Controller + Context + View
Use when:
- module owns business rules, validations, or branching state transitions
- user actions mutate domain state
- behavior requires automated verification
Lightweight Module
Structure:
Controller + Context + View
Use when:
- module is display/navigation/confirmation only
- no independent business rules are present
Rule:
- upgrade to standard five-layer as soon as business rules appear
Dependency Rules
Allowed:
UseCase -> domain/services/RawData/ResultController -> UseCase/RawData/Result/Context/View/UI-local eventsContext -> child context/value objectsView -> Context/UI-local events
Forbidden:
UseCase -> Context/View/rendering typesRawData/Result -> Context/ViewContext -> UseCase/ViewView -> UseCaseView -> global business eventsView -> domain state mutation
Event Communication Rules
Event Ownership
View -> Controlleruses UI-local events only- UI-local events are not global business contracts
- business/domain modules must not consume UI-local event semantics
Safety Requirements
- validate sender ownership in
Controller - scope handling to the active UI instance
- keep subscribe/unsubscribe symmetric
Interaction Flow
Standard Module
External Flow
-> create/bind UseCase
-> open UI via Controller
Controller
-> UseCase action
-> RawData/Result
-> BuildContext
-> View refresh
View
--(UI-local event)--> Controller
Lightweight Module
External Flow
-> open UI via Controller(userData)
Controller
-> BuildContext(userData)
-> View refresh
View
--(UI-local event)--> Controller
Naming and Folder Conventions
Recommended folders:
UI/<Domain>/UseCaseUI/<Domain>/RawDataUI/<Domain>/ControllerUI/<Domain>/ContextUI/<Domain>/View
Recommended naming:
XXXFormUseCaseXXXFormRawDataXXXFormControllerXXXFormContext,XXXItemContext,XXXAreaContextXXXResult,XXXActionResult
Testing Policy
Policy:
- if a UI has a
UseCaseand automated tests are added, use EditMode tests for theUseCase
Priority coverage:
- initial model generation
- business branch and validation behavior
- action result correctness
- boundary and invalid input handling
Manual verification focus:
- first open
- interaction refresh
- partial refresh
- close and reopen
- null/invalid userData behavior
Anti-Patterns
Do not allow:
UseCasereturningContextRawDatacarrying*ContextViewsubscribing global business events- direct domain mutation inside
View - skipping
Controlleras module entry - module marked lightweight while carrying business state transitions
Delivery Checklist
Use this checklist before marking work complete:
- classify each module as standard or lightweight
- verify business rules sit in
UseCaseonly - verify
Contextis built only inController - verify
RawDatahas no presentation model leakage - verify
Viewis render-and-emit only - verify UI-local events are scoped and sender-checked
- verify dependency direction constraints pass
- verify tests/manual checks match the testing policy