디자인 패턴

이 페이지에서는 추천되는 디자인 패턴과 안티 패턴에 대해 다룹니다.

note
이 문서에 디자인 패턴을 추가할 때는 해당 패턴이 해결하는 문제를 명확히 명시해야 합니다. 디자인 안티 패턴을 추가할 때는 미리 방지하는 문제를 명확히 명시해야 합니다.

패턴

다음 디자인 패턴은 일반적인 문제를 해결하기 위한 제안된 접근 방식입니다. 특정 패턴이라고 해서 항상 문제를 잘 해결하는 것은 아닙니다. 여러분의 상황에서 해당 패턴이 적절한지 신중하게 평가하십시오.

안티 패턴

안티 패턴은 처음에는 좋은 접근 방식처럼 보일 수 있지만, 보다 많은 해를 끼치는 것으로 입증되었습니다. 이러한 패턴은 일반적으로 피해야 합니다.

GitLab 코드베이스 전반에는 이러한 안티 패턴의 과거적인 사용 사례가 있을 수 있습니다. 신중하게 사용하여 이러한 레거시 패턴을 사용하는 코드를 다룰 때 리팩터링할지 여부를 결정하십시오.

note
새로운 기능에 대해서는 안티 패턴이 반드시 금지되는 것은 아니지만, 강력히 권장하는 대체 방법을 찾을 것을 권장합니다.

언제 Shared Global Object 패턴이 실제로 적절할까요?

Shared Global Object는 무언가를 전역적으로 접근 가능하게 하는 문제를 해결합니다. 이 패턴은 다음과 같은 경우에 적절할 수 있습니다:

  • 어떤 책임이 실제로 전역적이고 애플리케이션 전반에서 참조되어야 하는 경우(예: 전체 애플리케이션에서 사용되는 이벤트 버스).

이러한 시나리오에서도 부수 효과가 이해하기 어려울 수 있으므로 Shared Global Object 패턴을 피하는 것을 고려하십시오.

참고 자료

더 많은 정보는 Global Variables Are Bad on the C2 wiki를 참조하십시오.

싱글톤

고전적인 싱글톤 패턴은 한 가지 인스턴스만 존재하도록 하는 접근 방식입니다.

다음은 이 패턴의 예입니다:

class MyThing {
  constructor() {
    // ...
  }
  
  // ...
}

MyThing.instance = null;

export const getThingInstance = () => {
  if (MyThing.instance) {
    return MyThing.instance;
  }
  
  const instance = new MyThing();
  MyThing.instance = instance;
  return instance;
};

싱글톤이 야기하는 문제는 무엇인가요?

어떤 것의 한 가지 인스턴스만 존재해야 한다는 가정은 큰 가정입니다. 대부분의 경우, 싱글톤은 오용되어 자신과 그것을 참조하는 모듈 간에 매우 강한 결합을 유발합니다.

의존성 주입

의존성 주입은 모듈의 의존성을 외부에서 주입받도록 선언하여 결합을 분리하는 접근 방식입니다 (예: 생성자 매개변수를 통한 주입, 명백한 의존성 주입 프레임워크, 심지어 Vue의 provide/inject을 통해서도).

// bad - Vue 컴포넌트가 싱글톤에 결합됨
export default {
  created() {
    this.mediator = MyFooMediator.getInstance();
  },
};

// good - Vue 컴포넌트가 의존성을 선언함
export default {
  inject: ['mediator']
};
// bad - 싱글톤이 생명주기에 관한 확신이 없으므로 여기서 초기화함
export class Foo {
  constructor() {
    Bar.getInstance().init();
  }
  
  stuff() {
    return Bar.getInstance().doStuff();
  }
}

// good - 이 의존성을 생성자 인수로 받자
// 또한 생명주기를 관리하는 것은 우리의 책임이 아님
export class Foo {
  constructor(bar) {
    this.bar = bar;
  }
  
  stuff() {
    return this.bar.doStuff();
  }
}

이 예시에서 mediator의 생명주기와 구현 세부 정보는 모두 컴포넌트 외부 (아마도 페이지 진입점)에서 관리됩니다.