본문 바로가기
개발/Javascript

[js] 팩토리 패턴(ft. 프로토 타입, Object.create(), 코드 중복 방지 방법)

by 코딩하는 갓디노 2021. 2. 23.

팩토리 패턴

 

디자인 패턴 중, 
팩토리 패턴에 대하여 알아보겠습니다. 

 

객체에서 중복되는 코드를 팩토리 패턴을 사용하여,
코드를 줄이거나 제거할 수 있습니다. 

 

BEFORE

let friend1 = {
  name: '박지수',
  age: 20,
  job: 'nurse',
  sex: 'female',
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

let friend2 = {
  name: '박지석',
  age: 39,
  job: 'cops',
  sex: 'male',
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

let friend3 = {
  name: '강주동',
  age: 16,
  job: 'programmer',
  sex: 'male',
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

name, age, job, sex는 다르지만,
type과 personality 함수는 중복이 됩니다. 

 

팩토리 패턴

다른 부분 매개변수로 넣고, return 시켜 매개변수를 객체에 대입하고,
공통되는 부분은 함수 안에 넣어줍니다. 

AFTER: 팩토리 패턴

function friendMaker(name, age, job, sex) { //다른 부분 매개변수
  return {
    name: name, //매개변수 객체로 대입
    age: age,
    job: job,
    sex: sex,
    type: 'friend', //공통 부분
    personality: function() { 	//공통 부분
      console.log('nice');
    }
  }
}

let friend1 = friendMaker('박지수', 30, 'nurse', 'female');
let friend3 = friendMaker('강주동', 16, 'programmer', 'male');
console.log(friend1);
console.log(friend3);

 

결과

{name: "박지수", age: 30, job: "nurse", sex: "female", type: "friend", …}
age: 30
job: "nurse"
name: "박지수"
personality: ƒ ()
sex: "female"
type: "friend"
__proto__: Object

{name: "강주동", age: 16, job: "programmer", sex: "male", type: "friend", …}
age: 16
job: "programmer"
name: "강주동"
personality: ƒ ()
sex: "male"
type: "friend"
__proto__: Object

 

프로토 타입

· 객체에서 공통되는 속성을 프로토타입으로 설정하여 프로토타입과 참조 관계를 만듭니다. 
· 객체의 중복되는 코드를 하나의 프로토타입 변수로 선언하고,
변수.__proto__ =  프로토타입 변수로 설정합니다.
· __proto__는 생략해도 됩니다.

변수.__proto__ =  프로토타입 변수

 

 

AFTER: 프로토 타입

let prototype = {
  //공통되는 부분
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

let friend2 = {
  name: '박지석',
  age: 39,
  job: 'cops',
  sex: 'male',
}
friend2.__proto__ = prototype;
console.log(friend2);

 

결과

{name: "박지석", age: 39, job: "cops", sex: "male"}
age: 39
job: "cops"
name: "박지석"
sex: "male"
__proto__:
personality: ƒ ()
type: "friend"
__proto__: Object
friend2.__proto__
//result: {type: "friend", personality: ƒ}
friend2.__proto__.type
//result: "friend"

 

중복되는 부분을 프로토 타입으로 설정하는 이유

나중에 객체의 값을 변경되었을 때,
일일이 모든 변수의 값을 변경할 필요 없이, 프로토타입 변수에서 한번만 변경하면 되므로
공통되는 속성의 변경, 추가, 삭제가 용이합니다.  

예제1

prototype.type = 'family'
console.log(friend2);
//result: 
{name: "박지석", age: 39, job: "cops", sex: "male"}
age: 39
job: "cops"
name: "박지석"
sex: "male"
__proto__:
personality: ƒ ()
type: "family" //type이 family로 변경
__proto__: Object

 

예제2

prototype.city = 'seoul' //새로운 객체 설정
friend2.city
//result :"seoul"

 

팩토리 패턴+프로토 타입

let prototype = {
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

function friendMaker(name, age, job, sex) {
  let friend = {
    name: name,
    age: age,
    job: job,
    sex: sex,
  }
  friend.__proto__ = prototype;
  return friend
}

friendMaker('박지수', 30, 'nurse', 'female');

 

결과

{name: "박지수", age: 30, job: "nurse", sex: "female"}
age: 30
job: "nurse"
name: "박지수"
sex: "female"
__proto__:
personality: ƒ ()
type: "friend"
__proto__: Object

 

Object.create()

MDN Web Dos에서의 Object.prototype.__proto__ 는 
Deprecated(This feature is no longer recommended.) 라고 되어있습니다. 
즉, 프로토타입을 즉 권고하지 않는다고 나와있습니다. 

대체방법으로 Object.create로 프로토타입을 적용합니다. 

 

예제

let prototype = {
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

Object.create(prototype);
//result: 
//  {}
//  __proto__: 
//    personality: ƒ ()
//    type: "friend"
//    __proto__: Object

 

BEFORE: 프로토 타입 사용시 

let prototype = {
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

function friendMaker(name, age, job, sex) {
  let friend = {
    name: name,
    age: age,
    job: job,
    sex: sex,
  }
  friend.__proto__ = prototype;
  return friend
}

friendMaker('박지수', 30, 'nurse', 'female');

 

AFTER: Object.create()로 변경

let prototype = {
  type: 'friend',
  personality: function() {
    console.log('nice');
  }
}

function friendMaker(name, age, job, sex) {
  let friend = Object.create(prototype);
  friend.name = name;
  friend.age = age;
  friend.job = job;
  friend.sex = sex;
  return friend;
}

friendMaker('박지수', 30, 'nurse', 'female');

 

결과

{name: "박지수", age: 30, job: "nurse", sex: "female"}
age: 30
job: "nurse"
name: "박지수"
sex: "female"
__proto__:
personality: ƒ ()
type: "friend"
__proto__: Object
반응형

댓글