반응형


[javascript] Singleton 싱글톤




싱글턴의 싱글은 혼자의 싱글이 맞습니다. 

객체를 만들 때, 하나의 생성자로 여러 객체를 만들 수 있었습니다. 

하지만 싱글턴은 필요에 의해 단 하나 객체만을 만들 때 사용합니다. 아래 처럼요.

var obj = {
  a: 'hello',
  b: function() {
    alert(this.a);
  }
};

?? 엄청 간단하네요. 사실 객체 리터럴이 바로 싱글턴 패턴의 대표적인 예입니다. 저 객체는 단 하나밖에 존재하지 않죠. 하지만 모든 속성이 다 공개되어 있다는 단점이 있습니다. 비공개로 만드는 게 바로 제대로 된 싱글턴입니다.

var singleton = (function() {
  var instance;
  var a = 'hello';
  function initiate() {
    return {
      a: a,
      b: function() {
        alert(a);
      }
    };
  }
  return {
    getInstance: function() {
      if (!instance) {
        instance = initiate();
      }
      return instance;
    }
  }
})();
var first = singleton.getInstance();
var second = singleton.getInstance();
console.log(first === second); // true;

코드가 확 길어졌네요. 차근히 살펴보면 쉽습니다. IIFE로 비공개 변수를 가질 수 있게 만들어줍니다. 그리고 그 안에 instance변수와 initiate 함수를 만들어줍니다. initiate 함수 안의 내용이 실제 객체의 내용입니다. 위의 obj 객체와 비교하면 a가 비공개 변수가 되었네요.

IIFE로 즉시 반환되는 부분(return)을 보시죠. getInstance라는 메소드를 가진 객체를 반환하는데, getInstance 함수를 호출하는 순간 내부적으로 initiate 함수가 호출되고, instance에 아까 그 객체의 내용이 저장되고 동시에 반환됩니다. getInstance가 여러 번 호출됐을 경우에는 코드를 보시면 이미 instance 객체가 있는 경우에는 initiate를 거치지 않고 바로 반환하는 것을 알 수 있습니다.

first와 second 변수를 보면 두 번 다 getInstance 함수를 호출했는데요. 결과적으로 두 변수는 같습니다. first 때 initiate된 객체를 second 때도 똑같이 반환받았기 때문이죠. 즉, 아무리 호출해도 기존에 있던 객체는 복사되는 것도 아니고 그냥 그대로 반환됩니다. 싱글턴 패턴은 모듈 패턴을 변형한 디자인 패턴입니다.

싱글턴을 언제 써야할 지 잘 모르겠나요? 처음 네임스페이스를 만들 때 사용하면 됩니다! 예를 들어 게임을 만든다고 치면, 게임 객체를 싱글턴으로 만드는 겁니다. 게임 내의 모든 것을 감싸고 있는 객체를 말이죠. 게임을 실행했을 때 게임은 한 번만 켜져야하기 때문에 싱글턴이 적절합니다.

세 번째는 생성자 패턴입니다. 이것도 이미 배웠죠? 상속을 배울 때 다뤘습니다! 대부분의 객체는 이 패턴으로 만들게 됩니다. 특히 상속이 필요할 때는 제일 많이 쓰이죠. 모듈 패턴과 생성자 패턴을 조합해서 코드를 보기 좋게 만들 수 있습니다.

function Vehicle(name, speed) {
  this.name = name; this.speed = speed;
}
Vehicle.prototype.drive = function () {
  console.log(this.name + ' runs at ' + this.speed)
}; 

function 부분과 prototype 부분으로 따로 떨어져 있는 이 코드를 하나로 묶어줍시다.

var Vehicle = (function() {
  function Vehicle(name, speed) {
    this.name = name; this.speed = speed;
  }
  Vehicle.prototype.drive = function () {
    console.log(this.name + ' runs at ' + this.speed);
  };
  return Vehicle;
})();

생성자와 프로토타입을 모두 Vehicle 변수 안에 넣었습니다. 변수 Vehicle과 생성자 Vehicle 이름이 같아서 걱정하시는 분이 있을 수도 있는데 IIFE라서 바로 변수 Vehicle에 생성자 Vehicle이 덮어씌워집니다.

이외에도 빌더 패턴, 팩토리 패턴, 중재자 패턴, 옵저버 패턴, 메소드 체이닝 패턴 등이 있는데 고급 강좌에서 다뤄보겠습니다. (메소드 체이닝 패턴은 자주 사용됩니다. 28강 턴제 게임 만들기에서 알려드리겠습니다!)

다음 시간에는 자바스크립트 함수형 프로그래밍에 대해 알아보겠습니다.



ref : https://www.zerocho.com/category/JavaScript/post/57541bef7dfff917002c4e86


반응형

+ Recent posts