Mixin 패턴
상속 없이 객체에 기능을 추가한다
📜 원문: patterns.dev - mixin pattern
📜 번역: https://patterns-dev-kr.github.io/design-patterns/mixin-pattern/
Mixin은 상속 없이 어떤 객체나 클래스에 재사용 가능한 기능을 추가할 수 있는 객체입니다.
Mixin은 단독으로 사용할 순 없고 상속 없이 객체나 클래스에 기능을 추가하는 목적으로 사용됩니다.
앱에서 여러 강아지를 만들어야 한다고 가정해 볼 때 아래 강아지 클래스는 name 프로퍼티 외에 다른 프로퍼티를 가지고 있지 않습니다.
class Dog {
constructor(name) {
this.name = name
}
}
강아지는 이름 외에도 짖거나 꼬리를 흔들거나 신나게 놀 수 있어야 합니다.
Dog클래스에 직접 정의하는 대신 bark, wagTail, play를 프로퍼티로 가진 믹스인을 만들 수 있죠.
const dogFunctionality = {
bark: () => console.log('Woof!'),
wagTail: () => console.log('Wagging my tail!'),
play: () => console.log('Playing!'),
}
Object.assign 메서드를 이용해 dogFuncionality 믹스인의 기능을 Dog 프로토타입에 추가할 수 있습니다.
아래 예시에서는 Dot.prototype에 프로퍼티들을 추가하고 있습니다. 이 경우 새로 만들어지는 Dog 클래스의 인스턴스들은
Dog 의 프로토타입 객체에 추가된 dogFunctionality의 기능들을 사용할 수 있습니다.
class Dog {
constructor(name) {
this.name = name
}
}
const dogFunctionality = {
bark: () => console.log('Woof!'),
wagTail: () => console.log('Wagging my tail!'),
play: () => console.log('Playing!'),
}
Object.assign(Dog.prototype, dogFunctionality)
아래 예시는 믹스인으로 기능이 추가된 Dog의 클래스를 테스트해보고 있습니다.
const pet1 = new Dog('Daisy')
pet1.name // Daisy
pet1.bark() // Woof!
pet1.play() // Playing!
상속 없이 객체에 기능을 추가할 수 있지만 믹스인 자체는 상속을 사용할 수 있습니다.
대부분의 포유류는 걷거나 잠을 잘 수 있는데 강아지는 포유류이니 똑같이 걷거나 잘 수 있어야 합니다.
아래 예제에서는 walk, sleep 프로퍼티를 가진 animalFunctionality믹스인을 만들고 있습니다.
const animalFunctionality = {
walk: () => console.log('Walking!'),
sleep: () => console.log('Sleeping!'),
}
위에 언급했던 것 처럼 Object.assign을 사용하여 dogFunctionality에 animalFunctionality의 프로퍼티를 추가할 수 있습니다.
const animalFunctionality = {
walk: () => console.log('Walking!'),
sleep: () => console.log('Sleeping!'),
}
const dogFunctionality = {
bark: () => console.log('Woof!'),
wagTail: () => console.log('Wagging my tail!'),
play: () => console.log('Playing!'),
walk() {
super.walk()
},
sleep() {
super.sleep()
},
}
Object.assign(dogFunctionality, animalFunctionality)
Object.assign(Dog.prototype, dogFunctionality)
이제 만들어지는 Dog 클래스의 인스턴스들은 모두 walk, sleep 메서드를 사용할 수 있게 되었습니다.
Window 객체는 WindowOrWorkerGlobalScope와 WindowEventHandler 의 믹스인으로 구성되어 있기 때문에
setTimeout, setInterval, indexedDB, isSecureContext 같은 프로퍼티를 사용할 수 있습니다.
WindowOrWorkerGlobalScope는 믹스인이기 때문에 해당 믹스인을 직접 사용할수는 없죠.
React (ES6 이전)
ES6 클래스 문법이 소개되기 전에 믹스인은 React에서 컴포넌트에 기능을 추가하기 위해 종종 사용되었습니다.
'React개발팀은 mixin을 사용하지 말아 주세요.' 라는 글과 함께 컴포넌트의 믹스인이 복잡도를 증가시키고 재사용하기 어렵게 만든다고 이야기했죠.
대신 React개발팀은 지금은 훅에 의해 대체 가능하지만 고차 컴포넌트를 사용하길 권장했었습니다.
믹스인은 상속을 하지 않고도 객체의 프로토타입에 특정 기능들을 주입할 수 있습니다.
다만 객체의 프로토타입을 직접 수정하는 것은 의도하지 않은 프로토타입 프로퍼티의 수정으로 이어질 수 있어 주의가 필
요합니다.
참조
- Functional Mixins - Eric Elliott
- Mixins - JavaScript Info
'프로그래밍(Basic) > 디자인 패턴(JS)' 카테고리의 다른 글
[바미] HOC 패턴 (0) | 2022.09.24 |
---|---|
[바미] Mediator/Middleware 패턴 (0) | 2022.09.23 |
[바미] Module 패턴 (0) | 2022.09.21 |
[바미] Observer 패턴 (1) | 2022.09.19 |
[바미] Container/Presentational 패턴 (0) | 2022.09.15 |