cs

프론트엔드 아키텍쳐를 알아보자 (2) Redux, Observer-Observable, Atomic

ssoonn 2025. 1. 14. 11:45

이전글: 프론트엔드 아키텍쳐를 알아보자 (1) MVC, MVVM, Flu프론트엔드 아키텍쳐

 

1. Redux

여러 컴포넌트가 공유하는 상태를 관리하기 위한 라이브러리.

*Flux 패턴을 이용한 대표적인 구현체이다.

 

*recap: flux패턴은 데이터의 흐름이 한 방향으로만 흘러가도록 하는 아키텍쳐이다.

View를 각각의 MVC 컴포넌트 관점으로 보는 것이 아니라 하나의 큰 View로 본다.

 

1. 사용자가 View에서 이벤트 발생 -> Action 객체가 생성됨

2. Dispatch 메소드를 통해 이 Action이 Store로 전달

3. Middleware가 있는 경우, Action 처리

4. Reducer는 현재 상태와 Action을 받아 새로운 상태를 반환

5. Store는 이 새로운 상태를 저장

6. 상태가 변경되면 View가 이를 감지하여 스스로 업데이트

 

View

  • 사용자 인터페이스
  • 사용자의 입력(Input)을 감지하고, 이를 Actions으로 변환하여 Dispatcher에게 전달

Actions

  • 상태 변경을 위한 지시사항
  •   Action의 종류를 나타내는 문자열인 type과 상태 변경에 필요한 추가 데이터 payload를 포함한다.

Dispatch

  • ActionStore로 보내기 위해 사용되는 메서드
  • Dispatcher 역할을 대신하며, Action을 트리거

Store

  • dispatchAction을 받고 상태를 업데이트
  • MiddlewareReducer를 통해 상태 변경을 처리

Middleware(선택적)

  • ActionReducer에 도달하기 전에 중간에 실행되는 함수
  • 비동기 작업 처리, 로깅, 데이터 변환 등

Reducer

  • Actions을 기반으로 State를 변경하는 순수 함수
  • 이전 State와 Action을 입력받아 새로운 State를 반환

 

1.1 Redux 코드로 보기

const { createStore } = require('redux'); // Redux의 핵심 요소를 가져오기

// 1. Action 정의
const incrementAction = {
  type: 'INCREMENT', // Action의 종류를 나타내는 문자열
  payload: 1         // 상태 변경에 필요한 추가 데이터 (옵션)
};

// 2. Reducer 정의: 상태 변경 로직
const initialState = { count: 0 }; // 초기 상태

function counterReducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT': // new state 반환
      return { count: state.count + action.payload };
    default:       // 알 수 없는 Action은 현재 상태를 그대로 반환
      return state;
  }
}

// 3. Store 생성
// Store는 상태를 보관하고, Action을 통해 상태를 변경하며, 상태 변경을 구독
const store = createStore(counterReducer);

// 4. View를 위한 상태 변경 구독: 상태가 변경될 때마다 호출될 함수를 등록
store.subscribe(() => {
  console.log('State updated:', store.getState());
});

// 5. Action을 Dispatch: Action을 Store에 전달하여 상태 변경을 트리거
store.dispatch(incrementAction); // { count: 1 }

// 6. 또 다른 Action Dispatch
store.dispatch({ type: 'INCREMENT', payload: 2 }); // { count: 3 }

 

Redux는 기본적으로 동기적 상태 관리를 위한 설계이기 때문에, 비동기 데이터의 흐름이 복잡하다는 단점이 존재한다.

(비동기 작업을 위해서 미들웨어가 필요하다.)

 

 

2. Observer-Observable (옵저버 패턴)

유튜브같다. 어떤 객체 상태(유튜브 채널)을 구독하고 있는 구독자에게, 변경(동영상 업로드)되었을 때 알림을 보내는 패턴이다.

 

 

1. Observer들은 Observable에 등록(subscribe)한다.

2. Observable의 상태가 변경되면, 등록된 모든 Observer에게 알림 전송

3. Observer는 알림을 받고, 필요한 작업 수행

 

 

Observable (subject)

  • 상태를 보유하고 있으며, 상태가 변경되면 Observer들에게 알림 전송
  • Observer 객체 등록/제거 메서드 제공

Observer

  • Observable의 상태 변화를 감지하는 객체
  • Observable로부터 상태 변경 알림을 받으며, 필요에 따라 자신의 상태나 행동을 변경

 

2.1 Observer 코드로 보기

// Observable 클래스 정의
class Observable {
  constructor() {
    this.observers = []; // Observer 리스트
  }

  // Observer 등록
  subscribe(observer) {
    this.observers.push(observer);
  }

  // Observer 제거
  unsubscribe(observer) {
    this.observers = this.observers.filter(subscriber => subscriber !== observer);
  }

  // 상태 변경 시 모든 Observer에게 알리기
  notify(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}

// Observer 클래스 정의
class Observer {
  constructor(name) {
    this.name = name;
  }

  // Observable에서 알림을 받으면 호출되는 메서드
  update(data) {
    console.log(`${this.name} received update:`, data);
  }
}


// e.g.
// Observable 인스턴스 생성
const observable = new Observable();

// Observer 인스턴스 생성
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');

// Observer를 Observable에 등록
observable.subscribe(observer1);
observable.subscribe(observer2);

// 상태 변경 시 알림
observable.notify('New Data Available');

// Observer2를 구독 해지
observable.unsubscribe(observer2);

// 다시 상태 변경 시 알림
observable.notify('Another Update');

 

 

3. Atomic

UI 디자인, 개발에서 컴포넌트를 구성하고 조직화하는 방법론.

컴포넌트를 재사용 하능하게 하기 위해 잘게 쪼개는 것이다.

 

Atoms (원자)

  • UI의 가장 기본적인 구성 요소.
  • 더이상 쪼갤 수 없는 작은 단위로, HTML 태그 하나 혹은 최소한의 기능을 가진 요소들
  • 예시: 버튼, 입력 필드, 레이블 등

Molecules (분자)

  • 독립적인 기능을 수행할 수 있는 최소한의 단위로, 여러 Atoms가 모여 하나의 기능을 제공
  • 예시: 입력 필드와 버튼을 결합한 검색 양식

Organisms (생명체)

  • 여러 Molecules와 Atoms가 결합하여 더 복잡한 UI의 섹션을 구성
  • 페이지의 주요 부분을 이루며, 다양한 데이터와 상호작용을 처리
  • 예시: 네비게이션 바, 헤더, 푸터

Templates (템플릿)

  • Organisms를 배치하여 전체 페이지의 레이아웃을 정의한다.
  • 데이터가 없는 상태에서의 구조만을 제공하며, 반복적으로 사용할 수 있는 페이지의 틀
  • 예시: 블로그 글 목록 페이지 레이아웃

Pages (페이지)

  • Templates에 실제 데이터를 추가하여 최종 사용자에게 제공되는 UI를 구성한다.
  • 예시: 실제 블로그 글이 채워진 블로그 페이지

 

3.1 Atomic 코드로 보기

import React from 'react';

const noop = () => {};

// Atoms
const Button = ({ onClick, children, type }) => <button type={type} onClick={onClick}>{children}</button>;
const Label = ({ htmlFor, children }) => <label htmlFor={htmlFor}>{children}</label>;
const Input = ({ id, type, onChange, value = "" }) => <input id={id} type={type} onChange={onChange} value={value} />;
const Search = ({ onChange }) => <input type="search" onChange={onChange} />;
const NavMenu = ({ items }) => <ul>{items.map((item) => <li>{item}</li>)}</ul>;

// Molecules
const Form = ({ onSubmit }) => (
  <form onSubmit={onSubmit}>
    <Label htmlFor="email">Email:</Label>
    <Input id="email" type="email" onChange={noop} />
    <Button type="submit" onClick={noop}>Submit</Button>
  </form>
);

// Organisms
const Header = () => (
  <header>
    <Search onChange={noop} />
    <NavMenu items={[]} />
  </header>
);

const Content = ({ children }) => (
  <main>
    {children}
    <Form onSubmit={noop} />
  </main>
);

// Templates
const MainTemplate = ({ children }) => (
  <>
    <Header />
    <Content>{children}</Content>
  </>
);

// Pages
const HomePage = () => (
  <MainTemplate>
    <h2>My Form</h2>
    <p>This is a basic example demonstrating Atomic Design in React.</p>
  </MainTemplate>
);

 

 

 

refference

 

[React-Redux] 개념부터 기본 사용법 까지

리덕스의 개념과 적용방법에 대한 스터디(1) 작성중

velog.io

 

Redux Fundamentals, Part 1: Redux Overview | Redux

The official Fundamentals tutorial for Redux: learn the fundamentals of using Redux

redux.js.org

 

Diving into the great observer pattern in javascript

Design patterns are an international language, they're also a great way of dealing with problems, sometimes you'll be able to notice when a specific pattern is useful and other times you'll have to think a little harder to figure out which one to use (or i

enmascript.com

↑옵저버 패턴 with 쟈스 예시. 읽어보시길 추천드립니다

 

Atomic Design Pattern: Structuring Your React Application

As we build scalable applications in React, we often encounter challenges in managing the growing complexity of component structures. The…

rjroopal.medium.com