Skip to content

ausrasul/js_architecture_patterns

Repository files navigation

Architecture Patterns Demonstrated

This repo showcases several frontend architectural patterns side‑by‑side. You can run the dev server and navigate between routes to see each pattern in isolation and then all combined.

1. MVVM (Model–View–Presenter style)

Location: src/components/MVVM/

Pieces:

  • model.js – Pure data source (simulated async calls, rotating text data)
  • presenter.js – Orchestrates user intent (button click) -> model calls -> pushes state fragments
  • view.jsx – Pure, stateless rendering of props (no business logic)

Value:

  • Easy to test presenter & model independently
  • Clear separation between data retrieval and UI
  • Predictable change surface when adding new interactions

2. Store Pattern

Location: src/stores/

Stores (auth_store.js, stats_store.js) implement a minimal observer pattern:

  • onChange(cb) subscription
  • publish() internal fan‑out
  • Simple state container that can be shared by unrelated components (e.g., stats across dashboards)

Value:

  • Decouples producers (services/presenters) from consumers (views)
  • Enables multiple views to stay in sync without prop drilling
  • Provides a natural place for caching & aggregation logic

3. Service Layer

Location: src/services/

Examples:

  • auth_service.js – Handles login, user retrieval, and pushes results into auth_store
  • multichannel.js – Manages a WebSocket connection + channel subscription fan‑out

Value:

  • One boundary for side effects (HTTP, WS). Pure logic never directly touches network APIs
  • Swappable / mockable for tests or storybook scenarios
  • Central place for retries, instrumentation, auth token refresh, etc.

4. Multi-Channel Streaming

Location: src/components/MultiChannel/ + services/multichannel.js

Demonstrates two independent real-time feeds (chart and orderDepth) subscribing via the same service. Each presenter only cares about its slice, not about socket lifecycle.

Value:

  • Prevents duplicate socket connections
  • Encapsulates reconnection & message routing
  • Reduces UI coupling to transport details

5. Combined Composition (PuttingItAllTogether)

Location: src/components/PuttingItAllTogether/

Modular version integrates:

  • Auth (via service + store)
  • Stats (store updates + refresh action)
  • Text rotation (model/presenter pattern)
  • Streaming (chart + order depth) via WebSocket service

Each concern remains in its own file; presenter stitches them for the view. This mirrors how larger apps evolve: compose small, well‑scoped building blocks.

6. Intentional Anti‑Patterns for Contrast

We include progressively worse versions so you can compare:

Route File(s) Description
/all PuttingItAllTogether/ (modular) Clean separation: model + presenter + services + stores + view
/all-monolith PuttingItAllTogetherMonolith.jsx Single class using real services/stores, all orchestration inline
/all-inline PuttingItAllTogetherUltraMonolith.jsx Everything in one file (fake auth, inline intervals, no services/stores)
(legacy-style example) components/bad.jsx Large god component with mixed responsibilities

Key degradations as you move right:

  • Testability: pure units disappear
  • Reusability: logic welded to lifecycle methods
  • Cognitive load: must understand entire file to change one feature
  • Risk: higher chance of regression when editing unrelated logic
  • Extensibility speed: more lines touched per feature

Why This Matters

Adopting the modular approach yields:

  • Faster feature delivery (smaller, well-defined change sets)
  • Safer refactors (clear ownership of logic)
  • Easier onboarding (four nouns: service, store, presenter, view)
  • Cleaner test boundaries (pure model + presenter)
  • Centralized side-effect management (auth, sockets, API)

When NOT To Use Full Abstractions

For very small throwaway components, MVVM + store + service layers might be overkill. Start simple, then graduate patterns when:

  • Logic is reused in 2+ places
  • Side-effects need retry/metrics
  • State must synchronize across routes/components
  • Real-time + request/response flows intersect

Quick Start

npm install
npm run server &
npm run dev

Navigate to the routes mentioned above to explore the differences.

Possible Next Enhancements

  • Introduce a lightweight selector layer for derived store state
  • Provide unit tests for a presenter & model as reference ...

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages