Skip to content

javascript_in_depth_8

paul edited this page Apr 20, 2017 · 1 revision

๋””์ž์ธ ํŒจํ„ด ์‹ค์šฉ - ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด

ํ˜ธ์ถœ ๋Œ€์ƒ์ด ๋˜๋Š” ๊ฐ์ฒด์— ์ถ”๊ฐ€ ๊ธฐ๋Šฅ๋“ค์„ ์ž์œ ๋กญ๊ฒŒ ์ถ”๊ฐ€ํ•˜๋Š” ํŒจํ„ด์ด๋‹ค.

ํ™œ์šฉ

๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์œ ์šฉํ•˜๊ฒŒ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์€ ๋ฐ”๋กœ ๊ฒ€์ฆ ๋„๊ตฌ์ด๋‹ค. ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์ด์šฉํ•ด ๊ฒ€์ฆ ๋„๊ตฌ๋ฅผ ๋ชจ๋“ˆํ™”ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ž…๋ ฅ ์–‘์‹์ด ์—ฌ๋Ÿฌ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š” ํŽ˜์ด์ง€์—์„œ๋Š” ๊ณตํ†ต ๋ชจ๋“ˆ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์†์‰ฝ๊ฒŒ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

ํŠน์ง•

๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด์˜ ์žฅ์ ์€ ํ•œ ๋ฒˆ ์ฒด๊ณ„๋ฅผ ๋งŒ๋“ค์–ด๋‘๋ฉด ํ—ˆ์šฉ๋˜๋Š” ๋ฒ”์œ„ ์•ˆ์—์„œ๋Š” ํ™•์žฅํ•˜๊ณ  ์œผ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ํŽธ๋ฆฌํ•˜๋‹ค๋Š” ์ ์ด๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ˜๋Œ€๋กœ ์ฒซ ๋ฒˆ์งธ ์ฒด๊ณ„๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์–ด๋ ค์šธ ์ˆ˜๋„ ์žˆ๊ณ , ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ”์œ„๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ  ๋‚œ ๋‹ค์Œ, ํŠน์ •ํ•œ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์†Œ์Šค๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉด์„œ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ๋‹ค์†Œ ์–ด๋ ค์šธ ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

์˜ˆ์ œ

// ํผ ๊ฒ€์ฆ์„ ์œ„ํ•œ ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด ์‹ค์šฉ

<html>
<body>
    <form id="personalInformation">
        <label>First name: <input type="text" class="validate" data-validate-rules="required alphabet" name="firstName"></input></label><br/>
        <label>Last name: <input type="text" class="validate" data-validate-rules="required alphabet" name="lastName"></input></label><br/>
        <label>Age: <input type="text" class="validate" data-validate-rules="number" name="age"></input></label><br/>
        <label>Gender: <select class="validate" data-validate-rules="required">
            <option>Male</option>
            <option>Female</option>
        </select></label><br/>
        <input type="submit"></input>
    </form>

    <script>
    (function () {
        var formPersonalInformation = document.getElementById("personalInformation"),
            validator = new Validator(formPersonalInformation);

        function Validator (form) {
            this.validatingForm = form;
            form.addEventListener("submit", function () {
                if (!validator.validate(this)) {
                    event.preventDefault();
                    event.returnValue = false;
                    return false;
                }
                alert("Success to validate"); 
                return true;
            });
        }

        Validator.prototype.ruleSet = {};
        Validator.prototype.decorate = function (ruleName, ruleFunction) {
            this.ruleSet[ruleName] = ruleFunction;
        }
        Validator.prototype.validate = function (form) {
            var validatingForm = form || this.validatingForm,
                inputs = validatingForm.getElementsByClassName("validate"),
                length = inputs.length,
                i, j,
                input,
                checkRules, rule, ruleLength;

            for(i = 0 ; i < length ; i++) {
                input = inputs[i];
                if (input.dataset.validateRules) {
                    checkRules = input.dataset.validateRules.split(" ");
                    ruleLength = checkRules.length;
                    for (j = 0 ; j < ruleLength ; j++) {
                        rule = checkRules[j];
                        if (this.ruleSet.hasOwnProperty(rule)) {
                            if (!this.ruleSet[rule].call(null, input)) {
                                return false;
                            }
                        }
                    }
                }
            }
        };

        validator.decorate("required", function (input) {
            if (!input.value) {
                alert(input.name + " is required");
                return false;
            }
            return true;
        });

        validator.decorate("alphabet", function (input) {
            var regex = /^[a-zA-Z\s]*$/;
            if (!regex.test(input.value)) {
                alert(input.name + " has to be only alphabets");
                return false;
            }
            return true;
        });

        validator.decorate("number", function (input) {
            var regex = /^[0-9]*$/;
            if (!regex.test(input.value)) {
                alert(input.name + " has to be only numbers");
                return false;
            }
            return true;
        });
    }());
    </script>
</body>
</html>

Example

๊ฐ์ฒด ๊ธฐ๋ฐ˜ ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด

๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด์€ ๊ฒ€์ฆ ๋„๊ตฌ ์™ธ์—๋„ ๊ฐ์ฒด์ง€ํ–ฅ ๊ฐœ๋…์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ํ•˜๋‚˜์˜ ๊ฐ์ฒด์— ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๊ธฐ๋Šฅ๋“ค์„ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ๊ธฐ์กด์˜ ๊ฐ์ฒด์— ์ถ”๊ฐ€๋กœ ๊พธ๋ฉฐ์ง„ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋‚ผ ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์Œ์€ ๋‹ค์–‘ํ•œ ์ปดํ“จํ„ฐ๋ฅผ ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์ด์šฉํ•ด์„œ ๋‹ค๋ฅด๊ฒŒ ์ƒ์„ฑํ•˜๊ณ  ๋‹ค๋ฅธ ๋ถ€ํ’ˆ์„ ์ปดํ“จํ„ฐ์— ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฐ€๊ฒฉ์„ ์•Œ์•„๋ณด๋Š” ์˜ˆ์ด๋‹ค.

// ๊ฐ์ฒด๊ธฐ๋ฐ˜ ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด
(function () {
    function Computer(name) {
        this.name = name;
        this.price = 0;
        this.parts = [];
    }

    Computer.prototype = {
        showPrice: function () {
            console.log(this.name + " costs $" + this.price);
        },
        showParts: function () {
            var partString = "- Parts information\n",
                length = this.parts.length,
                i;

            for (i = 0 ; i < length ; i++) {
                partString += this.parts[i].name + ": $" + this.parts[i].price + "\n";
            }
            console.log(partString + "\n- Total: $" + this.price);
        },
        decorate: function (part) {
            this.price += part.price;
            this.parts.push(part);
        }
    };

    function ComputerDecorator() {
        this.decorateParts = {};
    }
    ComputerDecorator.prototype.decorateComputer = function (computer, partName) {
        if (this.decorateParts.hasOwnProperty(partName)) {
            computer.decorate(this.decorateParts[partName]);
            console.log("Decorating " + computer.name + " with " + partName);
        }
        return computer;
    };
    ComputerDecorator.prototype.addDecoratePart = function (partName, price) {
        this.decorateParts[partName] = {
            name: partName,
            price: price
        };
    };

    var computerDecorator = new ComputerDecorator();
    computerDecorator.addDecoratePart("CPU", 200);
    computerDecorator.addDecoratePart("8GB memory", 100);
    computerDecorator.addDecoratePart("4GB memory", 50);

    console.log("1. Home computer");
    var homeComputer = new Computer("Home computer");
    homeComputer = computerDecorator.decorateComputer(homeComputer, "CPU");
    homeComputer = computerDecorator.decorateComputer(homeComputer, "4GB memory");
    homeComputer.showPrice();
    homeComputer.showParts();

    console.log("\n2. Work computer");
    var workComputer = new Computer("Work computer");
    workComputer = computerDecorator.decorateComputer(workComputer, "CPU");
    workComputer = computerDecorator.decorateComputer(workComputer, "8GB memory");
    homeComputer.showPrice();
    workComputer.showParts();
}());

Example

ํ•จ์ˆ˜ ๊ธฐ๋ฐ˜ ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด

ํ•จ์ˆ˜์—๋„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด์„ ์ ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค. ํ”„๋ฝ์‹œ ํŒจํ„ด์˜ ๋ž˜ํผ ๊ธฐ๋Šฅ์„ ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด, ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๋„๋ก ์‘์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

// ๋ชจ๋‹ˆํ„ฐ๋ง ๊ธฐ๋Šฅ์„ ์œ„ํ•œ ๋ฐ์ปค๋ ˆ์ดํ„ฐ ํŒจํ„ด๊ณผ ํ”„๋ฝ์‹œ ํŒจํ„ด์˜ ์กฐํ•ฉ
(function () {
    var monitorTool,
        car,
        wrapperFunction;

    monitorTool = (function () {
        var functionSequence = [];
        return {
            decorate: function (name, func) {
                functionSequence.push({
                    name: name,
                    func: func });
            },
            monitor: function (func) {
                var length = functionSequence.length;
                for (i = 0 ; i < length ; i++) {
                    functionSequence[i].func.apply(this, arguments);
                }
            }
        };
    }());

    monitorTool.decorate("before", function (func) {
        console.log(func.name + " function has started at " + Date.now());
    });
    monitorTool.decorate("decorated", function (func) {
        func.apply(this, Array.prototype.slice(arguments, 1));
    });
    monitorTool.decorate("after", function (func) {
        console.log(func.name + " function has finished at " + Date.now());
    });

    wrapperFunction = monitorTool.monitor;

    car = {
        beep: function beep() {
            alert("BEEP"); },
        brake: function brake() {
            alert("STOP!");
        },
        accelerator: function accelerator() {
            alert("GO");
        }
    };

    function wrap(func, wrapper) {
        return function() {
            var args = [func].concat(Array.prototype.slice.call(arguments));
            return wrapper.apply(this, args);
        };
    }

    function wrapObject(obj, wrapper) {
        var prop;
        for(prop in obj) {
            if (obj.hasOwnProperty(prop) && typeof obj[prop] === "function") {
                obj[prop] = wrap(obj[prop], wrapper);
            }
        }
    }


    wrapObject(car, wrapperFunction);

    console.log("A. car.accelerator() monitor");
    car.accelerator();

    console.log("\nB. car.beep() monitor");
    car.beep();

    console.log("\nC. car.brake() monitor");
    car.brake();

}());

Example

Clone this wiki locally