Mixin

소개(Introduction)

전통적인 객쳬지향 계층과 함께, 재사용 가능한 컴포넌트로 부터 클래스를 빌드하는 또 다른 일반적인 방법으로, 간단한 부분클래스를 결합하여 빌드하는 것입니다. 스칼라 등의 언어를 통해서, 믹스인에 대한 개념과 특성은 익숙할 수 있을 것이며, 패턴은 JavaScript 커뮤니티에서도 어느 정도의 인기를 얻었습니다.

예시 코드(Code Sample)

아래 코드에서는 TypeScript에서 mixin의 모델링 방식을 보여줍니다. 코드를 본 후, 작동 방식을 살펴보도록 하겠습니다.

// Disposable Mixin
class Disposable {
    isDisposed: boolean;
    dispose() {
        this.isDisposed = true;
    }

}

// Activatable Mixin
class Actiavatable {
    isActive: boolean;
    activate() {
        this.isActive = true;
    }
    deactivate() {
        this.isActive = false;
    }
}

class SmartObject {
    constructor() {
        setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500);
    }

    interact() {
        this.activate();
    }
}

interface SmartObject extends Disposable, Activatable {}
applyMixins(SmartObject, [Disposable, Activatable]);

let smartObj = new SmartObject();
setTimeout(() => smartObj.interact(), 1000);

////////////////////////////////////////
// In your runtime library somewhere
////////////////////////////////////////

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
        });
    });
}

예시 알아보기(Understanding the sample)

예시 코드는 mixin을 수행하는 두 클래스로 시작합니다. 두 클래스는 각각 부분적인 기능에 집중되어 있음을 알 수 있습니다. 이후에는 두 기능을 모두 사용하여 새로운 클래스를 만들기 위해 이들을 혼합(mix)할 것입니다.

// Disposable Mixin
class Disposable {
    isDisposed: boolean;
    dispose() {
        this.isDisposed = true;
    }

}

// Activatable Mixin
class Activatable {
    isActive: boolean;
    activate() {
        this.isActive = true;
    }
    deactivate() {
        this.isActive = false;
    }
}

다음으로, 두 mixin의 결합을 처리 할 클래스를 만듭니다. 이것이 어떻게 작동하는지 더 자세히 살펴 보겠습니다.

class SmartObject {
    ...
}

interface SmartObject extends Disposable, Activatable {}

첫 번째 사항은 SmartObject 클래스에서 DisposableActivatable을 확장하는 대신 SmartObject 인터페이스에서 확장한다는 것입니다. Declaration merging으로 인해 SmartObject 인터페이스가 SmartObject 클래스에 혼합됩니다.

클래스를 인터페이스로 취급하고 DisposableActivatable 뒤에있는 유형 만 구현이 아닌 SmartObject 유형으로 혼합합니다. 이것은 우리가 클래스에서 구현에서 mixin을 제공해야 한다는 것을 의미합니다. 그 외에는 mixin의 사용을 피할 수 있습니다.

마지막으로 클래스에 구현에서, mixin을 혼합(mix)합니다.

applyMixins(SmartObject, [Disposable, Activatable]);

마지막으로, 우리를 위해 mixin을 수행 할 도우미 함수를 만듭니다. 그러면 각 mixin의 속성이 실행되고 mixin의 대상으로 복사되어 독립형 속성을 구현합니다.

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
        });
    });
}

results matching ""

    No results matching ""