디자인 패턴

    728x90
    반응형

     

     

    디자인 패턴이란?

    반복적으로 나타나는 프로그래밍 문제를 해결하기 위한 해결책입니다.

    쉽게 말해 개발자들끼리 협업을 잘할 수 있도록 코드들의 패턴을 짬과 코드의 질, 효율성을 높히는 것이라 부를 수 있다는 것을 알 수 있다.

    많은 예시중 각각 몇개씩만 소개하려고 한다.

     

    장점

    • 개발자 간의 원활한 의사소통
    •  소프트웨어 구조 파악 용이
    • 재사용을 통한 개발 시간 단축
    • 설계 변경 요청에 대한 유연한 대처
    • 불필요한 리소스 낭비 방지

    단점

    • 객체지향 설계/구현 위주로 사용된다.
    • 초기 투자 비용 부담

     

     

    반응형

     

    *생성패턴

    1. 싱글톤 패턴 (Singleton Pattern)

    • 하나의 클래스에 오직 하나의 인스턴스만을 가지는 패턴.
    • 하나의 클래스를 기반으로 여러개의 개별적인 인스턴스를 만들 수 있지만,
    • 그렇게 하지않고 하나의 클래스를 기반으로 단 하나의 인스턴스만을 만들어서 이를 기반으로 로직을 만듬.
    • 보통 데이터베이스 연결 모듈에 많이 사용한다.
    • 자바스크립트에서는 이미 객체 리터럴을 이용한 객체 생성 방법이 싱글톤 패턴과 동일

     

    장점

    • 하나의 인스턴스를 기반으로 다른 모듈들이 공유해서 사용하기 때문에 인스턴스를 생성할 때 드는 비용이 줄어듭니다.
    • '인스턴스생성에 많은 비용'이 드는 I/O 바운드 작업에 많이 사용합니다.

    * I/O 바운드 : 디스크 연결, 네트워크 ㅇ녀결, 데이터베이스 연결

     

    단점

    • 의존성이 높아진다.
    • TDD ( Test Driven Development ) 를 할 때 걸림돌이 됩니다.
    • TDD를 할때 단위 테스트를 주로 하는데, 단위 테스트는 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야합니다.
    • 하지만 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴이므로 각 테스트마다 '독립적인' 인스턴스를 만들기가 어렵다.

    * 의존성 : 종속성이라고도 하며 A가 B에 의존성이 있다는 것은 B변경 사항에 대해 A또한 변해야 된다는 것을 의미.

    // 싱글톤 패턴 예시
    class Singleton {
      static instance = null;
    
      constructor() {
        if (!Singleton.instance) {
          Singleton.instance = this;
        }
        return Singleton.instance;  
      }
    }
    
    // 예시 사용
    const singleton1 = new Singleton();
    const singleton2 = new Singleton();
    
    console.log(singleton1 === singleton2); // 출력: true

     

     

     

    2. 팩토리 패턴(Factory Patter)

    • 비슷한 객체를 공장에서 찍어내듯이 반복적으로 생성할 수 있게 하는 패턴
    • 컴파일 시점에 구체적인 타입(클래스)을 몰라도 객체 생성이 가능하다
    • 팩토리 패턴의 가장 흔한 사례는 Object() 를 이용한 객체 생성시, 주어지는 값의 타입에 따라 String, Boolean, Number 등으로 객체가 생성되는 것이다.
    // 팩토리 패턴 구현 예제
    function CarMaker() {}
    CarMaker.prototype.drive = function () {
      return "Vroom, I have " + this.doors + "doors";
    };
    CarMaker.factory = function (type) {
      var constr = type,
          newcar;
    
      // 생성자 존재하지 않으면 에러발생
      if (typeof CarMaker[constr] !== "function") {
        throw {
          name: "Error",
          message: constr + "doesn't exist"
        };
      }
    
      // 생성자 존재 확인 후 부모 상속
      if (typeof CarMaker[constr].prototype.drive !== "function") {
        CarMaker[constr].prototype = new CarMaker();
      }
    
      newcar = new CarMaker[constr]();
    
      return newcar;
    };
    
    CarMaker.Compact = function () {
      this.doors = 4;
    };
    CarMaker.Convertible = function () {
      this.doors = 2;
    };
    CarMaker.SUV = function () {
      this.doors = 24;
    };
    // --
    
    // 위 패턴을 이용한 결과
    var corolla = CarMaker.factory("Compact");
    var solstice = CarMaker.factory("Convertible");
    corolla.drive();  // "Vroom, I have 4 doors"
    solstice.drive(); // "Vroom, I have 2 doors"

     

     

     

     

     

     

     

    *구조패턴

    1. 컴포지트 패턴 (Composite Pattern)

    • 객체를 트리 구조로 구성하여 단일 객체와 객체의 그룹을 동일한 방식으로 취급할 수 있도록 합니다.
    • 개별 객체와 복합 객체를 일관된 방식으로 처리할 수 있도록 합니다.
    • 주로 UI 컴포넌트 구현이나 데이터 구조에서 사용됩니다.
    • 예를 들어, 트리 형태로 구성된 메뉴 시스템이나 파일 시스템 등이 이 패턴을 사용합니다.
    // 컴포지트 패턴 예시
    class Component {
      constructor(name) {
        this.name = name;
      }
    
      display() {
        console.log(this.name);
      }
    }
    
    class Composite extends Component {
      constructor(name) {
        super(name);
        this.children = [];
      }
    
      add(component) {
        this.children.push(component);
      }
    
      display() {
        console.log(this.name);
        for (let child of this.children) {
          child.display();
        }
      }
    }
    
    // 예시 사용
    const root = new Composite('Root');
    const branch1 = new Composite('Branch 1');
    const leaf1 = new Component('Leaf 1');
    const leaf2 = new Component('Leaf 2');
    
    root.add(branch1);
    branch1.add(leaf1);
    branch1.add(leaf2);
    
    root.display();

     

     

    2. 프록시 패턴 (Proxy Pattern)

    • 프록시 패턴은 접근을 제어하고 비용 절감하며 복잡성을 줄이기 위해 사용
    • 프록시는 네트워크 연결, 큰 메모리 객체와 같은 비용이 많이 들거나 복제가 불가능한 리소스 같은 형태에서 사용
    • Lazy Initialization (게으른 초기화) 로 어플리케이션의 부하를 줄여준다.
    • 만약 파일을 읽어야 한다면 파일을 직접 읽지 않고 프록시 객체를 통해 접근. 프록시는 반복된 파일 접근에 대해 캐싱 처리 등을 수행할 수 있다. 프록시 패턴을 적용하는 상황은 다음과 같다.

     

     

     

     

     

    *행동패턴

    1. 옵저버 패턴 (Observer Pattern)

    • 옵저버 패턴은 객체 간의 일대다 의존성을 정의하고, 한 객체의 상태 변경이 다른 객체들에게 자동으로 알림을 전달하고 받는 패턴입니다.
    • 상태 변경을 관찰하고 해당 변경에 대한 알림을 수신하는 디자인 패턴입니다.
    • 이벤트 기반 프로그래밍에서 자주 사용되며, 주로 UI 업데이트나 데이터 변경을 감지하고 처리하는 데 사용됩니다.
    • 대표적으로 React의 상태 관리 라이브러리인 Redux나 Vue.js의 상태 관리 라이브러리 Vuex에서 이 패턴을 활용합니다. 또한 mouseover, keypress 와 같은 브라우저 이벤트
    • subscriber / publisher 패턴이라고도 한다.
    // 옵저버 패턴 예시
    class Subject {
      constructor() {
        this.observers = [];
      }
    
      addObserver(observer) {
        this.observers.push(observer);
      }
    
      notifyObservers(data) {
        for (let observer of this.observers) {
          observer.update(data);
        }
      }
    }
    
    class Observer {
      update(data) {
        console.log('Received data:', data);
      }
    }
    
    // 예시 사용
    const subject = new Subject();
    const observer1 = new Observer();
    const observer2 = new Observer();
    
    subject.addObserver(observer1);
    subject.addObserver(observer2);
    
    subject.notifyObservers('New data');

     

     

     

    2. 스트레터지 패턴 (Strategy Pattern)

    • 알고리즘을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만드는 패턴
    // 스트레터지 패턴 예시
    class Strategy1 {
        execute() {
            return 'Executing strategy 1';
        }
    }
    
    class Strategy2 {
        execute() {
            return 'Executing strategy 2';
        }
    }
    
    class Context {
        constructor(strategy) {
            this.strategy = strategy;
        }
    
        setStrategy(strategy) {
            this.strategy = strategy;
        }
    
        executeStrategy() {
            return this.strategy.execute();
        }
    }
    
    const context = new Context(new Strategy1());
    console.log(context.executeStrategy());  // 출력: Executing strategy 1
    
    context.setStrategy(new Strategy2());
    console.log(context.executeStrategy());  // 출력: Executing strategy 2

     

     

     

     

     

     

     

    참조!

    https://joshua1988.github.io/web-development/javascript/javascript-pattern-design/#observer-%ED%8C%A8%ED%84%B4

     

    Javascript Pattern 요약 - 디자인 패턴

     

    joshua1988.github.io

    https://meongae.tistory.com/97

     

    [디자인 패턴] ES6로 구현하는 디자인 패턴

    ※ 디자인 패턴 종류 ▶ 생성패턴 Constructor Factory Abstract Factory Prototype Singleton Builder ▶ 구조 패턴 Adapter Composite Module Decorator Facade Proxy FlyWeight Bridge ▶ 행동 패턴 Chain of Responsibility Command Observer Iter

    meongae.tistory.com

     

    https://www.youtube.com/watch?v=DHo8qRCtmGU&list=PLTC3gIv9IzFLblGSX7yf_4p9VeUqAr_9q

    728x90
    반응형

    '개발 지식' 카테고리의 다른 글

    CI / CD  (0) 2024.04.11
    API  (0) 2024.04.11
    this의 용법을 아는대로 설명하시오  (0) 2022.11.11
    GET, POST 방식 차이  (0) 2022.11.09
    함수선언문과 함수표현식의 차이  (0) 2022.11.03

    댓글