프록시 클래스를 사용한 동적 ES6 클래스 인스턴스화

22830 단어 javascriptbeginners
저는 사용자가 라이브 스트림을 위해 다양한 유형의 방송 그래픽을 만들 수 있는 프로젝트를 진행 중입니다. 기본Graphic 클래스가 있고 화면에서 재생될 다양한 종류의 그래픽에 대해 이를 확장할 수 있기 때문에 이것은 클래스를 사용하기에 좋은 장소입니다.

이것은 나중에 10개 또는 20개의 그래픽 하위 클래스 중 하나를 인스턴스화할 때 처리하기가 약간 어려울 수 있습니다. 논리적if/else 명령문을 사용하거나 모든 종류의 하위 클래스를 선별하기 위해switch 명령문을 사용하려고 하는 사람은 아무도 없습니다.

프록시 클래스를 입력합니다.

위의 예에 따라 기본Graphic 클래스가 있다고 가정해 보겠습니다.

class Graphic {
    _id = Date.now();
    position = [2,2];
    autoplay = false;
    entranceAnimation = {type: 'fade', direction: 'none', duration: 500, delay: 0};
    exitanimation = {type: 'fade', direction: 'none', duration: 500, delay: 0};
    isPlaying = false;

    constructor(options) {
        this.showName = options.showName;
        this.scene = options.scene;
    }

    play() {
        if(this.isPlaying === false) {
         this.isPlaying = true;
        }
    }

    stop() {
        if(this.isPlaying === true) {
            this.isPlaying = false;
        }
    }
}


이제 이 기본 클래스가 여기에 있으므로 모든 그래픽 하위 클래스에 대한 몇 가지 멋진 기본값을 가질 수 있으므로 Bug라는 하위 클래스를 만들어 보겠습니다(버그는 상단 모서리 중 하나에 표시되는 매우 간단한 그래픽일 뿐입니다).

class Bug extends Graphic {
    type = 'bug';
    position = [1,1];
    entranceAnimation = {type: 'fly', direction: 'left', duration: 500, delay: 500}
    exitAnimation = {type: 'fly', direction: 'left', duration: 500, delay: 0}

    constructor(options) {
        super(options);

        this.content = options.content;
    }
}


쿨하다, 쿨하다. 이제 버그를 인스턴스화할 수 있습니다.

const myFirstBug = new Bug({content: 'LIVE'});
console.log(myFirstBug);



Bug {
  _id: 1602690699857,
  position: [ 1, 1 ],
  autoplay: false,
  entranceAnimation: { type: 'fly', direction: 'left', duration: 500, delay: 500 },
  exitanimation: { type: 'fade', direction: 'none', duration: 500, delay: 0 },
  isPlaying: false,
  showName: undefined,
  scene: undefined,
  type: 'bug',
  exitAnimation: { type: 'fly', direction: 'left', duration: 500, delay: 0 },
  content: 'LIVE'
}

이것이 우리가 원하는 것입니다. 필요할 때 상속하거나 재정의할 수 있는 합리적인 기본 필드가 있는 기본 클래스입니다. 기본은 제대로 작동합니다.

이제 다른 유형의 그래픽LowerThird을 만들어 보겠습니다(일반적으로 화자의 이름과 제목 또는 화면에 있는 내용에 대한 세부 정보와 함께 화면 하단에서 재생되는 그래픽).

class LowerThird extends Graphic {
    position = [3,1];
    entranceAnimation = {type: 'scale', direction: 'left', duration: 700, delay: 0};
    exitAnimation = {type: 'scale', direction: 'left', duration: 700, delay: 0};

    constructor(options) {
        super(options);

        this.subjects = options.subjects;
    }
}


그리고 인스턴스화된 LowerThird:

const myLowerThird = new LowerThird(
    {
        subjects: [
            {
                title: 'John Brown',
                info: 'Radical Abolitionist'
            },
            {
                title: 'James Baldwin',
                info: 'Writer, Expatriot'
            }
        ]
    });

console.log(myLowerThird);



LowerThird {
  _id: 1602690699917,
  position: [ 3, 1 ],
  autoplay: false,
  entranceAnimation: { type: 'scale', direction: 'left', duration: 700, delay: 0 },
  exitanimation: { type: 'fade', direction: 'none', duration: 500, delay: 0 },
  isPlaying: false,
  showName: undefined,
  scene: undefined,
  exitAnimation: { type: 'scale', direction: 'left', duration: 700, delay: 0 },
  subjects: [
    { title: 'John Brown', info: 'Radical Abolitionist' },
    { title: 'James Baldwin', info: 'Writer, Expatriot' }
  ]
}

간단한 일이지만 우리는 누군가가 하루 종일 클래스를 만들고 인스턴스화하는 것을 보기 위해 여기에 있는 것이 아닙니다. 프록시 클래스가 도움이 되는 이유를 알아보기 위해 왔습니다.

누군가 새 그래픽을 만들 때 new LowerThird() 또는 new Bug() 또는 new HundredthGraphicType()를 호출하고 싶지 않습니다. 내 프로그램이 런타임에 인스턴스화해야 하는 그래픽의 하위 클래스를 결정하고 나를 위해 인스턴스화할 수 있기를 원합니다. this StackOverflow answer 에서 프록시 클래스의 분석을 볼 수 있습니다.

이것은 매우 간단한 패턴입니다. 생성자 매개변수가 만들고자 하는 클래스의 이름과 해당 클래스의 생성자에 전달하려는 옵션이 있는 클래스를 만듭니다. 그런 다음 ProxyClass 생성자 블록에서 return 문을 사용하여 새 클래스를 생성합니다.

여기 보세요:

class ProxyGraphic {
    constructor(className, options) {
        const graphicClasses = {
            Bug,
            LowerThird
        };

        return new graphicClasses[className](options);
    }
}


이제 새 클래스를 직접 인스턴스화하는 대신 모든 것을 프록시 클래스에 전달할 수 있으며 graphicClasses 개체에서 참조되는 클래스가 있는 한 올바른 종류의 그래픽을 인스턴스화합니다. 사용자가 선택하는 것에 따라 다른 종류의 클래스를 만들고 싶을 때 정말 유용합니다.

여기에 모든 것이 있습니다.

class Bug extends Graphic {
    type = 'bug';
    position = [1,1];
    entranceAnimation = {type: 'fly', direction: 'left', duration: 500, delay: 500}
    exitAnimation = {type: 'fly', direction: 'left', duration: 500, delay: 0}

    constructor(options) {
        super(options);

        this.content = options.content;
    }
}

class LowerThird extends Graphic {
    position = [3,1];
    entranceAnimation = {type: 'scale', direction: 'left', duration: 700, delay: 0};
    exitAnimation = {type: 'scale', direction: 'left', duration: 700, delay: 0};

    constructor(options) {
        super(options);

        this.subjects = options.subjects;
    }
}

class ProxyGraphic {
    constructor(className, options) {
        const graphicClasses = {
            Bug,
            LowerThird
        };

        return new graphicClasses[className](options);
    }
}

new ProxyGraphic('Bug', {content: 'LIVE'});


보고:

Bug {
  _id: 1602690769341,
  position: [ 1, 1 ],
  autoplay: false,
  entranceAnimation: { type: 'fly', direction: 'left', duration: 500, delay: 500 },
  exitanimation: { type: 'fade', direction: 'none', duration: 500, delay: 0 },
  isPlaying: false,
  showName: undefined,
  scene: undefined,
  type: 'bug',
  exitAnimation: { type: 'fly', direction: 'left', duration: 500, delay: 0 },
  content: 'LIVE'
}

좋아, 충분히 공평해. 그러나 요점은 우리가 원하는 동적 콘텐츠를 전달하여 프로그램에서 더 큰 유연성을 허용하는 것입니다. 페이지의 일부 입력 필드에 연결된 척하는 몇 가지 변수를 만들어 시뮬레이션해 보겠습니다.

let userSelectedGraphic = 'LowerThird';
let userInputOptions = {subjects: [{title: 'Billy Batson', info: 'Average Kid'}, {title: 'Clark Kent', info: 'Mild Mannered Reporter'}]};

new ProxyGraphic(userSelectedGraphic, userInputOptions);


보고:

LowerThird {
  _id: 1602691813627,
  position: [ 3, 1 ],
  autoplay: false,
  entranceAnimation: { type: 'scale', direction: 'left', duration: 700, delay: 0 },
  exitanimation: { type: 'fade', direction: 'none', duration: 500, delay: 0 },
  isPlaying: false,
  showName: undefined,
  scene: undefined,
  exitAnimation: { type: 'scale', direction: 'left', duration: 700, delay: 0 },
  subjects: [
    { title: 'Billy Batson', info: 'Average Kid' },
    { title: 'Clark Kent', info: 'Mild Mannered Reporter' }
  ]
}

그게 다야! 나는 이것이 꽤 유용하다는 것을 알았고 클래스를 훨씬 더 쉽게 사용할 수 있는 패턴이라고 생각합니다.

좋은 웹페이지 즐겨찾기