Dev./javascript

[JS] 중첩 클래스 정의하기

인쥭 2022. 9. 7. 18:28
반응형

클래스를 const varName = class ClassName {} 형태로 작성할 수 있는 점을 다음과 같이 이용할 수 있다.

'use strict';

describe('my-tests', () => {

    it('playground', async () => {
        const arm = 'add one arm';
        const leg = 'add two legs';
        const head = 'add small head';
        const body = 'add big body';
        
        const robot = Robot.builder
            .setArm(arm)
            .setLeg(leg)
            .setHead(head)
            .setBody(body)
            .build();
        
        expect(robot).toBeInstanceOf(Robot);
        expect(robot).toHaveProperty('arm', arm);
        expect(robot).toHaveProperty('leg', leg);
        expect(robot).toHaveProperty('head', head);
        expect(robot).toHaveProperty('body', body);
    });
});

class Robot {
    #arm;
    #leg;
    #head;
    #body;

    static #builder = class RobotBuilder {
        #arm;
        #leg;
        #head;
        #body;
        setArm(arm) {
            this.#arm = arm;
            return this;
        }
        setLeg(leg) {
            this.#leg = leg;
            return this;
        }
        setHead(head) {
            this.#head = head;
            return this;
        }
        setBody(body) {
            this.#body = body;
            return this;
        }
        build() {
            const param = {};
            if(this.#arm) param.arm = this.#arm;
            if(this.#leg) param.leg = this.#leg;
            if(this.#head) param.head = this.#head;
            if(this.#body) param.body = this.#body;

            return new Robot(param);
        }
    }

    static get builder() {
        return new this.#builder();
    }

    constructor({ arm, leg, head, body }) {
        this.#arm = arm;
        this.#leg = leg;
        this.#head = head;
        this.#body = body;
        console.log(`create robot with`, arm, leg, head, body);
    }

    get arm() { return this.#arm };
    get leg() { return this.#leg };
    get head() { return this.#head };
    get body() { return this.#body };
}