Prototype 패턴
동일 타입의 여러 객체들이 프로퍼티를 공유한다
📜 원문: patterns.dev - prototype pattern
📜 번역: https://patterns-dev-kr.github.io/design-patterns/prototype-pattern/
Prototype 패턴은 동일 타입의 여러 객체들이 프로퍼티를 공유할 때 유용하게 사용합니다.
Prototype은 JavaScript 객체의 기본 속성이므로 Prototype 체인을 활용할 수 있죠.
하나의 앱을 만들 때 동일한 타입의 여러 객체를 만들어내곤 합니다. ES6 의 클래스의 여러 인스턴스를 만들어 낼 때 유용하게 사용할 수 있죠.
여러 강아지 클래스를 만들어 보겠습니다. 예제에서 강아지는 이름을 가지고 있고. 짖을 수 있습니다.
class Dog {
constructor(name) {
this.name = name
}
bark() {
return `Woof!`
}
}
const dog1 = new Dog('Daisy')
const dog2 = new Dog('Max')
const dog3 = new Dog('Spot')
Dog 클래스의 생성자에서는 name 프로퍼티를 가지고 있고 클래스 자체적으로는 bark 프로퍼티를 가지고 있습니다.
ES6클래스를 사용하면 모든 프로퍼티는 클래스 자체에 선언되며 위의 코드에서 bark 는 자동으로 prototype 에 추가됩니다.
생성자의 prototype 프로퍼티 혹은 생성된 인스턴스의 __proto__ 프로퍼티를 통해 Prototype 객체를 확인할 수 있습니다.
💡 역자 주: __proto__ 는 비 표준이다. Object.getPrototypeOf는 표준이므로 이를 사용한다.
console.log(Dog.prototype)
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
console.log(dog1.__proto__)
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
어떤 인스턴스던 __proto__ 의 값은 Prototype 객체를 가리킵니다. 객체에 없는 프로퍼티에 접근하려 하는 경우 JavaScript는 이 프로퍼티가 나타날때 까지 prototype chain 을 거슬러 올라갑니다.
Prototype 패턴은 객체들이 같은 프로퍼티를 가져야 하는 경우 유용하게 쓰일 수 있습니다. 중복된 프로퍼티들이 존재하는 객체를 매번 생성하기 보다, Prototype에 프로퍼티를 추가하면 모든 인스턴스들이 Prototype 객체를 활용할 수 있습니다.
모든 인스턴스들이 Prototype에 접근 가능하기 때문에. 인스턴스를 만든 뒤에도 Prototype에 프로퍼티를 추가할 수 있습니다.
예제에서 강아지는 짖기만 가능했지만 놀 수도 있게 구현해 보죠. Prototype 객체에 play 프로퍼티를 추가하여 가능합니다.
Prototype “체인” 단어처럼 Prototype은 한 단계 이상도 존재할 수 있습니다. 지금까지 어떤 인스턴스의 proto 속성에 대해서 이야기 했지만 사실 Prototype 객체 자체도 proto속성을 가질 수 있습니다.
이제 다른 타입의 강아지를 만들어 보죠. 이 강아지는 Dog의 속성을 모두 가지고 있지만 하늘을 날 수 있습니다.
이 슈퍼 강아지는 Dog 클래스를 상속받아 fly 메서드를 구현하면 됩니다.
class SuperDog extends Dog {
constructor(name) {
super(name)
}
fly() {
return 'Flying!'
}
}
아래 예제에서는 Daisy 라는 강아지를 만들고 짖거나 하늘을 날 수 있게 하고 있습니다.
SuperDog 는 Dog 를 상속했습니다. 따라서 인스턴스 dog1 은 bark 메서드도 호출 할 수 있다. SuperDog 의 Prototype 객체의 proto 는 Dot.prototype을 가리키고 있습니다.
Prototype 체인이라 불리우는 이유가 명확해졌을것이다. 현재 객체에 없는 프로퍼티에 접근하려 하는 경우 JavaScript는 같은 이름의 프로퍼티를 찾을때까지 재귀적으로 객체의 proto 를 따라 거슬러 올라가게 됩니다.
Object.create
Object.create 메서드는 Prototype으로 쓰일 객체를 인자로 받아 새로운 객체를 만들어냅니다.
const dog = {
bark() {
return `Woof!`
},
}
const pet1 = Object.create(dog)
pet1 자체적으로는 아무런 프로퍼티도 없지만 dog 객체를 Prototype으로 사용하기 때문에 bark 메서드를 사용할 수 있습니다.
Object.create 는 단순히 객체가 다른 객체로부터 프로퍼티를 상속받을 수 있게 해 줍니다. 실행 결과로 생성되는 객체는
Prototype 체인으로 인해 인자로 넘어갔던 객체의 프로퍼티를 활용할 수 있는 것이죠.
Prototype 패턴은 어떤 객체가 다른 객체의 프로퍼티를 상속받을 수 있도록 해 줍니다.
Prototype 체인을 통해 해당 객체에 프로퍼티가 직접 선언되어 있지 않아도 되므로 메서드 중복을 줄일 수 있고 이는 메모리 절약으로 이어집니다.
참조
'프로그래밍(Basic) > 디자인 패턴(JS)' 카테고리의 다른 글
[바미] Observer 패턴 (1) | 2022.09.19 |
---|---|
[바미] Container/Presentational 패턴 (0) | 2022.09.15 |
[바미] Provider 패턴 (0) | 2022.09.13 |
[바미] Proxy 패턴 (0) | 2022.09.12 |
[바미] Singleton 패턴 (0) | 2022.09.02 |