디자인 패턴

프로그램 개발 과정 중 나타내는 문제들을 해결 하기 위한 해결책

디자인 패턴 ?

많은 문제에서는 공통점이 발견 되고 이를 해결 하려는 해결책에서도 유사점이 생긴다.

패턴 ?

Why use?

👍  의사 소통

👍  빠른 문제 해결

👍  재사용성

디자인 패턴 요소

패턴 이름(pattern name)

설계 어휘를 늘리는 일, 패턴 자체를 표현, 의사소통 원활

문제(problem)

설계 과정에서 있을 문제를 제시하며 패턴을 적용하는 것이 의미 있는 사례들을 정의하기도 한다.

해법(solution)

디자인 패턴은 문제에 대한 추상적인 설명을 제공하고 문제를 해결하기 위해서 클래스나 방법을 제공한다.

결과(consequence)

패턴의 결과는 시스템의 유연성, 확장성, 이식성 등의 커다란 영향을 준다. 그래서 이런 설게의 결과를 잘 정리하면 패턴들을 이해하고 적용하는데 도움이 된다.

 

Why use?

" 예쁜 코드 만들기 "

 에리히 감마(Erich Gamma)

리처드 헬름(Richard Helm)

랄프 존슨(Ralph Johnson)

존 블리시데스(John Vlissides)

Gang of Four

23가지의 패턴

생성(creational) 패턴

 객체의 생성 과정에 관여하는 패턴

구조(structural) 패턴  

클래스나 객체의 합성에 관한 패턴

행동(behavioral) 패턴

클래스나 객체들이 상호작용하는 방법과 책임을 분산하는 방법을 정의하는 패턴

자바스크립트 디자인 패턴

(feat. 자바스크립트 패턴과 테스팅)

자바스크립트 디자인 패턴

(feat. 자바스크립트 패턴과 테스팅)

" 어휘력을 늘려서 멋진 코드를 만들자 "

" 패턴의 범위는 다양하다 "

PascalCase

 

DoSomething

camelCase

 

DoSomething

콜백 패턴

👏  자바스크립트 함수는 일급 함수

👏  일급 함수는 함수가 인자가 될 수 있다

👏  콜백은 클로저다

function callbackFunction (callback) {
    let name = 'hong';
    callback(name);
}
 
function welcome() {
    let text = "welcome!!";
    callbackFunction(function (name) {
        console.log(`${name} ${text}`);
    });
}
 
welcome();

Callback hell !!

setTimeout(
    function(name) {
        var catList = name + ", ";
        setTimeout(
            function(name) {
                catList += name + ", ";
                setTimeout(
                    function(name) {
                        catList += name + ", ";
                        console.log('catList: ', catList)
                    },
                    1,
                    "Lynx"
                );
            },
            1,
            "Jaguar"
        );
    },
    1,
    "Panther"
);

// catList:  Panther, Jaguar, Lynx,
setTimeout(getPanther, 1, 'Panther');

var catList = '';

function getPanther(name) {
  catList = name + ', ';

  setTimeout(getJaguar, 1, 'Jaguar');
}

function getJaguar(name) {
  catList += name + ', ';

  setTimeout(getLynx, 1, 'Lynx');
}

function getLion(name) {
  catList += name;

  console.log('catList: ', catList);
}

// catList:  Panther, Jaguar, Lynx,

그래도 뭔가 모자라다 !!

프로미스 패턴

👏  가독성이 떨어지는 콜백 패턴

👏  예외처리의 곤란함

 

try {
    setTimeout(function() {
         throw '에러다'; 
        }, 0);
} catch (e) {
    console.log('잡아봐라~!');
    console.log(e);
}

// result : 에러다
const hello = function(name) {
    return new Promise(function(resolve, reject) {
        if (name) {
            console.log(`hello ${name}`);
            resolve(name);
        }
        reject('who are you?');
    });
}

hello('hong')
    .then(result => {
        console.log('result', result);
    })
    .catch(error => {
        console.log('error', error);
    });

// hello hong
// result hong

프로미스 체이닝

let catList = '';
const addCat = function(cat) {
    return new Promise(function(resolve, reject) {
        if (cat) {
            catList += cat + ", ";
            resolve(catList);
        }

        reject('Where is cat?');
    });
}

addCat('doondoon')
    .then(catList => {
        return addCat('Lynx');
    })
    .then(catList => {
            return addCat('Jaguar');
    })
    .then(catList => {
        return addCat('Jaguar');
    })
    .then(catList => console.log(`catList: ${catList}`))
    .catch(error => console.log(error));

// catList: doondoon, Lynx, Jaguar, Jaguar,

메모이제이션패턴

👏  기억하기 위해 메모 하기

 

var fibonacci = (function() {
    var save = {};
    var fibo = function(number) {
      if (number < 2) {
        return number;
      } else {
        var saved1 = save[number - 1] || fibo(number - 1);
        var saved2 = save[number - 2] || fibo(number - 2);
        var result = saved1 + saved2;
        save[number] = result;
        console.log(saved1, saved2, result);
        return result;
      }
    };
    return fibo;
  })();
  fibonacci(5); // 1 0 1, 1 1 2, 2 1 3, 3 2 5, 5
  fibonacci(5); // 3 2 5, 5
var factorial = (function() {
    var save = {};
    var fact = function(number) {
      if (number > 0) {
        var saved = save[number - 1] || fact(number - 1);
        var result = number * saved;
        save[number] = result;
        console.log(saved, result);
        return result;
      } else {
        return 1;
      }
    };
    return fact;
  })();
  factorial(7); // 1 1, 1 2, 2 6, 6 24, 24 120, 120 720, 720 5040
  factorial(7); // 720 5040

싱글톤 패턴

👏  하나의 객체만 존재한다

👏  객체리터럴을 사용한 객체 생성은 이미 싱글톤이다

const singleton = (function () {
    let instance;

    function init() {
        // 객체
        return {
            publicMethod: function() {
                this.publicProperty += 1;
            },
            publicProperty: 0
        }
    };

    return {
        getInstance: function() {
            if (!instance) {
                instance = init();
            }

            return instance;
        }
    }
})();

let firstInstance = singleton.getInstance();
let secondInstance = singleton.getInstance();

firstInstance.publicMethod();
firstInstance.publicMethod();

console.log(firstInstance.publicProperty, secondInstance.publicProperty); // 2, 2
console.log(firstInstance === secondInstance); // true

팩토리 패턴

👏  객체를 찍어내는 공장

const Factory = function() {
    this.customer = function(type) {
        let _customer;

        if (type === 'child') {
            _customer = new child();
        } else if (type === 'student') {
            _customer = new teenager();
        } else if (type === 'adult') {
            _customer = new adult();
        }

        _customer.getInfo = function() {
            console.log(this.price, this.grade);
        }

        return _customer;
    }
}

const child = function () {
    this.price = 6000;
    this.grade = 'child';
}

const teenager = function () {
    this.price = 9000;
    this.grade = 'student';
}

const adult = function () {
    this.price = 12000;
    this.grade = 'adult';
}

const factory = new Factory();

const customer1 = factory.customer('child');
const customer2 = factory.customer('student');
const customer3 = factory.customer('adult');

customer1.getInfo();
customer2.getInfo();
customer3.getInfo();

// 6000 'child'
// 9000 'student'
// 12000 'adult'

프록시 패턴

👏  실제 객체에 접근 할 경우 Wrapper(래퍼)

👏  실제 객체와 접근자 간 중계자

function PhoneBook() {
    this.dictionary = {
        '이승민': '01012341234',
        '이현섭': '01023456789',
        '오유근': '01077777777'
    };
}

PhoneBook.prototype.get = function(name, callback) {
    var self = this;
    setTimeout(function() {
        callback(self.dictionary[name]);
    }, 3000);
}

function PhoneBookProxy() {
    var phoneBook = new PhoneBook();
    var viewCount = 0;

    return {
        get: function(name, callback) {
            viewCount++;
            phoneBook.get(name, callback);
        },

        getViewCount: function() {
            return viewCount;
        }
    };
}

let phoneBook = new PhoneBookProxy();

phoneBook.get('이승민', function(phoneNum) {
    console.log('phoneNum', phoneNum);
});
console.log('viewCount', phoneBook.getViewCount());

// 1
// 01012341234

수 많은 패턴들..

빌더, 커멘드, 데코레이터, 옵저버,

생성자, 모듈, 네임인터페이스, 샌드박스,

플라이웨이트, 전략 패턴, 복합체 패턴등등등..

sat10am - Javascript design pattern

By Seungwoo Hong

sat10am - Javascript design pattern

  • 422