Skip to content

JavaScript Design Patterns edward

jaewook0106 edited this page Oct 28, 2019 · 1 revision

JavaScript Design Patterns

Constructor Pattern 생성자 패턴

전통적인 객체지향 프로그래밍에 있어서 생성자(constructor)는 특별한 메서드로 새롭게 생성할 객체의 초기화에 사용되고 한번 생성된 객체는 메모리상에 저장이됩니다. 자바스크립트에서는 거의 모든 것이 객체이기에 객체 생성자에 대부분의 관심을 가지게 됩니다.

객체 생성자는 객체를 사용할 준비를하고 객체를 처음 생성 할 때 생성자에서 멤버 속성 및 메서드 값을 설정하는 데 사용할 수있는 인수를 받아들이는 특정 유형의 객체를 만드는 데 사용됩니다.

1. Object Creation

가장 일반적인 객세 생성하는 방법

2. Basic Constructors

function person(firstName,lastName){
  
  this.firstName = firstName;
  
  this.lastName = lastName;
  
  this.fullName = function(){
    return this.firstName + " " + this.lastName;
  }
  
}

var person1 = new person('Akash','Pal');
var person2 = new person('Black','Panther');
person1.fullName(); //"Akash Pal"
person2.fullName(); //"Black Panther"
person1 //{firstName: "Akash", lastName: "Pal", fullName: ƒ}
person2 //{firstName: "Black", lastName: "Panther", fullName: ƒ}

3. Constructor with prototypes.


Module Pattern 모듈 패턴

일반적으로 모듈 패턴은 원래 기존의 소프트웨어 엔지니어링에서 클래스에 대한 private 과 public한 캡슐화를 제공하는 방법으로 정의되었습니다.

자바스크립트에서 모듈 패턴은 단일 객체 내에 공개/비공개 메소드와 변수를 모두 포함할 수 있도록 클래스 개념을 더욱 모방하여 특정 부분을 글로벌 범위에서 차단하는 데 사용됩니다. 이 결과 페이지의 추가 스크립트에 정의된 다른 함수와 충돌할 가능성이 감소합니다.

var personModule = (function(){
  
  var firstName;
  var lastName;
  
  return{
    setName(f,l){
      firstName = f;
      lastName = l;
    },
    getName(){
      return firstName + " " + lastName;
    }
  }
  
})();

personModule.setName('akash','pal')
personModule.getName() //"akash pal"

Revealing Module Pattern 모듈 노출 패턴

개인 범위에서 모든 함수와 변수를 간단하게 정의하고 공개하고자하는 개인 기능에 대한 포인터가 있는 익명 객체를 반환하는 업데이트 된 패턴입니다.

var personModule = (function(){
  
  var firstName;
  var lastName;
  
  function setName(f,l){
    firstName = f;
    lastName = l;
  }
  
  function getName(){
    return firstName + " " + lastName;
  }
  
  return{
    setName:setName,
    getName:getName
  }
  
})();

personModule.setName('akash','pal');
personModule.getName(); //"akash pal"

Singleton Pattern 싱글톤 패턴

싱글톤 패턴은 클래스의 인스턴스화를 단일 객체로 제한하기 때문에 알려져 있습니다. 고전적으로 싱글톤 패턴이 존재하지 않는 경우 클래스의 새로운 인스턴스를 생성하는 메소드로 클래스를 작성하여 구현할 수 있습니다. 인스턴스가 이미 존재하는 경우 해당 객체에 대한 참조를 반환합니다.

var singleton = (function(){

  var instance;
  
  function init(){
    
    var name;
    
    this.setName = function(name){
       this.name = name;
    }
    
    this.getName = function(){
      return this.name;
    }
    
    return{
      setName:setName,
      getName:getName
    }
      
  }
  
  function getInstance(){
    
    if(!instance){
      instance = init();
    }
    
    return instance;
  }
    
  return{
    getInstance:getInstance
  }  
  
})();


var one = singleton.getInstance();
var two = singleton.getInstance();

//the two instance are same
one == two //true

one.setName('Akash');
two.getName(); //"Akash"

Observer Pattern 옵져버 패턴

옵저버는 객체(주체로 알려져 있음)가 객체(관찰자)에 따라 객체 목록을 유지하고 상태 변경을 자동으로 알려주는 디자인 패턴입니다.

  • Subject: 관찰자 목록을 유지하고 관찰자 추가 또는 제거를 용이하게 합니다.

  • Observer: 대상의 상태 변경을 알릴 필요가 있는 객체에 대한 업데이트 인터페이스를 제공합니다.

  • ConcreteSubject: 상태 변화에 대한 관찰자에게 알림을 알리고, ConcreteObservers의 상태를 저장합니다.

  • ConcreteObserver: ConcreteSubject에 대한 참조를 저장하고 상태가 주제와 일치하도록 관찰자에 대한 업데이트 인터페이스를 구현합니다.

Publish/Subscribe Pattern

옵져서 패턴은 주제 알림을 수신하려는 관찰자(또는 객체)가 이벤트를 발생시키는 객체(주제)에 관심을 구독해야합니다.

그러나 Publish/Subscribe 패턴은 알림을 수신하려는 객체(구독자)와 이벤트를 발생시키는 객체(게시자) 사이에있는 topic/event 채널을 사용합니다. 이 이벤트 시스템을 통해 코드는 가입자가 필요로하는 값을 포함하는 사용자 지정 인수를 전달할 수있는 응용 프로그램 특정 이벤트를 정의 할 수 있습니다. 여기서 아이디어는 구독자와 게시자 간의 종속성을 피하는 것입니다.

이는 적절한 이벤트 처리기를 구현하는 가입자를 게시자가 브로드 캐스트 한 토픽 알림을 등록하고 수신 할 수있게하므로 옵져버 패턴과 다릅니다.

이미지 주소 : https://miro.medium.com/max/3028/1*-HzQOW37lYfr2HWQRPDHvw.png

A Mediator is an object that coordinates interactions (logic and behavior) between multiple objects. It makes decisions on when to call which objects, based on the actions (or inaction) of other objects and input.

프로토타입 패턴은 프로토타입 상속을 기반으로하고 다른 객체의 프로토타입으로 작동하는 객체를 생성하는 것으로 생각할 수 있습니다.
프로토타입 객체 자체는 생성자가 생성하는 각 객체의 blueprint(청사진)를 효과적으로 사용됩니다. 사용된 생성자 함수의 프로토타입에 예를 들면 아래의 코드 샘플에 따라 name이라는 속성이 포함 된 경우 동일한 생성자에 의해 생성 된 각 객체에도 동일한 속성이 있습니다.

ECMAScript 5 표준에 정의 된 실제 프로토타입 상속에는 Object.create를 사용해야합니다.

function person(firstName,lastName){
  
  this.firstName = firstName;
  
  this.lastName = lastName;
  
}

person.prototype.fullName = function(){
    return this.firstName + " " + this.lastName;
}

var person1 = new person('Akash','Pal');
var person2 = new person('Black','Panther');
person1 //{firstName: "Akash", lastName: "Pal"}
person2 //{firstName: "Black", lastName: "Panther"}
person1.fullName() //"Akash Pal"
person2.fullName() //"Black Panther"

Object.create를 직접 사용하지 않는 프로토타입 패턴

Command 패턴은 메소드 호출, 요청 또는 오퍼레이션을 단일 오브젝트로 캡슐화하는 데 목적이 있으며 재량에 따라 실행할 수있는 메소드 호출을 매개 변수화하고 전달할 수 있습니다. 또한 액션을 구현하는 객체에서 액션을 호출하는 객체를 분리하여 구체적인 클래스(객체)를 교체 할 때 전반적인 유연성을 크게 향상시킬 수 있습니다.

var name = {
  fName:'aaa',
  lName:'bbb',
  setName:function(fName,lName){
    this.fName = fName;
    this.lName = lName;
  },
  getName:function(){
     return this.fName + " " + this.lName;
  }
}

name.execute = function(key){
   var methodName = name[key];
   var functionParamsArray = [].splice.call(arguments,1);
   return methodName.apply(name,functionParamsArray);   
}

name.execute('setName','Akash','Pal');
console.log(name.execute('getName'));//Akash Pal

Facades는 jQuery와 같은 JavaScript 라이브러리에서 종종 볼 수있는 구조적 패턴입니다. 구현은 광범위한 동작을 가진 메소드를 지원할 수 있지만 이러한 메소드의 "facade(정면)" 또는 제한된 추상화만 사용을 위해 공개됩니다.

Facades는 모듈 패턴과 같은 다른 패턴과 통합 될 수도 있습니다.

팩토리 패턴은 객체 생성 개념과 관련된 또 다른 생성 패턴입니다. 카테고리의 다른 패턴과 다른 점은 명시 적으로 생성자를 사용할 필요가 없다는 것입니다. 대신 팩토리는 객체를 생성하기위한 일반 인터페이스를 제공 할 수 있으며, 여기서 생성하려는 팩토리 객체의 유형을 지정할 수 있습니다.

function Bike(options){
  this.wheels = 2;
  this.color = options.color;
}

function Car(options){
  this.wheels = 4;
  this.color = options.color;
}

function VehicleFactory(){}

VehicleFactory.prototype.createVehicle = function(options){
		
    switch(options.type){
    	case 'Bike': 
          this.vehicleClass = Bike;
      break;
      case 'Car': 
          this.vehicleClass = Car;
      break;
      default: 
          this.vehicleClass = Bike;
    }
    
    return new this.vehicleClass(options);
}

var vehicleFactory = new VehicleFactory();

var bike = vehicleFactory.createVehicle({
	type:'Bike',
  color:'black'
});

console.log(bike); //Bike {wheels: 2, color: "black"}

var car = vehicleFactory.createVehicle({
	type:'Car',
  color:'white'
});

console.log(car); //Car {wheels: 4, color: "white"}

이미지 주소 : https://miro.medium.com/max/2976/1*vS04c6QeLjIL_oj_pc0CHA.png

Mixins은 기능 재사용을 위해 서브 클래스 또는 서브 클래스 그룹에 의해 쉽게 상속 될 수있는 기능을 제공하는 클래스입니다.

function Person(firstName,lastName){
  this.firstName = firstName; 
  this.lastName = lastName;
}

Person.prototype.fullName = function(){
    return this.firstName + " " + this.lastName;
}

function Superhero(firstName,lastName,powers){
  //super call
	Person.call(this,firstName,lastName);
  this.powers = powers;
}

Superhero.prototype = new Object(Person.prototype);

Superhero.prototype.showPowers = function(){
		return this.powers;
}

var superhero1 = new Superhero('Iron','Man',['Flying suit','Jarvis']);
console.log(superhero1.fullName() + '-' + superhero1.showPowers()); //Iron Man-Flying suit,Jarvis

var superhero2 = new Superhero('Captain','America',['strength','endurance','healing']);
console.log(superhero2.fullName() + '-' + superhero2.showPowers()); //Captain America-strength,endurance,healing
Clone this wiki locally