Front-end_dev

디자인패턴... 본문

ES6/Syntax

디자인패턴...

Eat2go 2017. 4. 5. 16:58

현재 진행중인 개인 프로젝트가 하나있는데 로직을 하나하나 구현할때마다 자꾸 flag같은 변수들(부산물들)이 나와서 이것을 한번 고쳐보자 해서 고안한 패턴입니다.


예를들어, 문제를 한 번 내보겠습니다.

상황1 : 나는 라이브러리 개발자이고 현재 만들고있는 라이브러리에서는 A라는 객체의 B라는 프로퍼티에 C값이 들어갔을 때 D라는 동작을 해야한다. 



솔루션 : 일단, C값이 들어왔을때 B라는프로퍼티가 그걸 인지할수있어야겠죠? 그리고나서 기본동작을 오버라이딩하고 D동작을 구현합니다.


그럼 여기서 방법은 수백가지가 될 수 있어요. 저는 처음에는 그중 하나인 flag같은 변수들을 만들어서 해결했었습니다.

근데 이런 부산물들이 계속나오게되는데 문제가 안될수도있긴 합니다만, 코딩실력은 더 좋아지진 않을 것 같습니다.


ES6에서는 proxy라는 기능이있습니다. 이걸로 이 문제를 해결하겠습니다.


실습준비물은 babel 이나 webpack이필요한데 webpack이 편하니까 webpack을 잘모르시는분들은 한 번 익혀보시기 바랍니다.

실습준비물에 babel같은 ES6 트랜스파일러가 필요한 이유는 import,export구문을 사용하기 위함인데 구지 import,export를 사용하지않아도됩니다. 그러면 한파일안에서 모든코드를때려박으면됩니다. 그러면 트랜스파일러는 따로필요없습니다.

 

디렉터리구조



proxyExample.js 

import {handlerSetfrom "./proxy_handlers";
import {proxingfrom "./object_to_proxyObject";

class someLibrary {
    constructor() {
        this.arr = [];
        this.foo = undefined;
    }

    output(value) {
        alert(value);
    }

    add() {
        this.arr.push('happy');
    }
}

let bar = new someLibrary();
let p = proxing(bar,handlerSet);
p.foo = 5;
p.foo;
p.arr[0] = 1;
p.arr.push(2);
p.arr[2] = 3;

proxy_handlers.js

const handlerSet = {
    get(target,prop,receiver) {
        switch(prop) {
            case 'foo' : return target[prop];
            break;
            case 'arr' : {
                if(target[prop].length === 3) {
                    console.log(`${prop}의 길이가 3이되었습니다! 그러므로 보너스로 happy라는 문자열을 하나더 넣겠습니다! `);
                    target.add();
                } 
                return target[prop];
            }
        }
    },
    set(target,prop,value,receiver) {
        switch(prop) {
            case 'foo' : {
                if(value >= 5) {
                    console.log(`${target}에 ${value}이상이 대입 되었습니다! 그러므로 output함수를 호출하겠습니다!`);
                    target.output(value);     
                }
            }
            break;
        }
        target[prop] = value;
        return true;
    }
}

export {handlerSet};

object_to_proxyObject.js

function proxing(whatObj,handler) {
    return new Proxy(whatObj,handler);
}

export {proxing};

webpack.config.js


module.exports = {
    entry : './proxyExample.js',
    output : {
        path : __dirname,
        filename : 'translate_proxy_Example.js'
    },
    module : {
        rules : [{
            test : /\.js$/,
            exclude : /node_modules/,
            use : [{
                loader : 'babel-loader',
                options : {
                    presets : ['es2017']
                }
            }]        
        }]
    }
}

proxyExample.html

<!DOCTYPE html>
<head>
</head>
<body>
</body>
<script src='translate_proxy_Example.js'>
</script>
</html>


코드에대한 설명은 따로 하지 않겠습니다 그리고 translate_proxy_Example.js 는 proxyExample.js를 ES5로 트랜스파일한 코드이므로 사진으로는 올리지 않겠습니다.

object_to_proxyObject.js

proxy_handlers.js

proxyExample.html

proxyExample.js

translate_proxy_Example.js

webpack.config.js