본문 바로가기

카테고리 없음

Overview of OOP patterns implementation in JavaScript (한글)

이 글은 아래 원문을 번역한 글로 의역이 있을 수 있습니다. 정확한 의미를 파악하고 싶으신 분은 원문을 참고해주시기 바랍니다.

 

원문: https://indepth.dev/posts/1495/js-design-patterns

저작권 정보: 


JavaScript에서의 OOP 패턴 구현 개요

 

이제 'Gang Of Four'에서 설명한 OOP의 설계 패턴을 살펴보고 JavaScript에서 구현되는 방식을 살펴보겠습니다.

디자인 패턴이란?

먼저 디자인 패턴의 진정한 정의를 이해해야 합니다. 소프트웨어 개발자는 어떤 방법으로든 코드를 작성할 수 있습니다. 단,  코드를 유지하는 방법에 큰 차이가 있습니다. 최대한 고려되어 작성된 코드는 아마추어보다 오래갈 것입니다. 따라서 올바른 코딩 스타일을 선택할 때 확장성이나 유지보수에 대해 걱정할 필요가 없습니다.

  • 설계 패턴의 역할은 전체적인 문제를 복잡하게 만들지 않는 솔루션을 구축하는 데 도움이 됩니다.
  • 패턴은 인터랙티브한 오브젝트 및 재사용이 많은 설계를 작성하는 데 도움이 됩니다.
  • 디자인 패턴은 객체 지향 프로그래밍에서 필수적인 개념입니다.

JavaScript의 디자인 패턴

  1. 추상 공장 (Abstract Factory)
  2. 빌더
  3. 팩토리
  4. 프로토타입
  5. 싱글턴

추상 공장

공장이란 무엇인가? 아이에게 공장을 뭐라고 설명하겠습니까? 공장은 우리가 물건을 생산하는 곳일 뿐이다. 예를 들어 장난감 공장에서는 장난감의 생산을 볼 수 있습니다. 정의와 마찬가지로 JavaScript의 팩토리(Factory in JavaScript)는 객체가 다른 객체를 생성하는 장소입니다.

모든 장난감 공장에서 테디베어와 변압기를 생산하는 건 아니죠?다른 종류의 장난감을 위한 별도의 장난감 공장이 있다.

장난감 공장은 항상 목적을 가지고 일한다. 마찬가지로 Abstract Factory는 테마로 작동합니다. Abstract Factory에서 가져온 객체는 공통 테마를 공유합니다.

 

예를 들어 JavaScript의 Abstract Factory에 대해 알아보겠습니다.

  1. 토이 팩토리를 위한 소프트웨어를 만들어야 해요.
  2. 저는 트랜스포머 영화를 주제로 한 장난감을 생산하는 부서가 있습니다. 그리고 스타워즈를 테마로 한 장난감을 취급하는 또 다른 부서입니다.
  3. 두 부서 모두 몇 가지 공통적인 특징과 독특한 주제를 가지고 있습니다.
function StarWarsFactory(){
this.create = function(name){
return new StarWarsToy(name)
}}

function TransformersFactory(){
this.create = function(name){
return new TransformerToy(name)
}}

function StarWarsToy(name){
this.nameOfToy = name;
this.displayName = function(){
console.log("My Name is "+this.nameOfToy);
}}

function TransformersToy(name){
this.nameOfToy = name;
this.displayName = function(){
console.log("My Name is "+this.nameOfToy);
}}

function buildToys(){
var toys = [];


var factory_star_wars = new StarWarsFactory();
var factory_transformers = new TransformersFactory();


toys.push(factory_star_wars.create("Darth Vader"));
toys.push(factory_transformers.create("Megatron"));

for(let toy of toys)
console.log(toy.displayName());
}

빌더

빌더의 역할은 복잡한 객체를 만드는 것입니다.클라이언트는 실제 작업에 대해 걱정할 필요 없이 최종 객체를 받게 됩니다. 대부분의 경우 빌더 패턴은 복합 객체의 캡슐화입니다. 주로 전체 과정이 복잡하고 반복적이기 때문입니다.

 

토이 팩토리를 어떻게 구현하는지, 빌더 패턴으로 확인해 봅시다.

  1. 나는 장난감 공장을 가지고 있다.
  2. 스타워즈 완구를 만드는 부서가 있어요.
  3. 스타워즈 부서 내에서 다스베이더 장난감을 많이 만들고 싶다.
  4. 다스 베이더 장난감을 만드는 과정은 두 단계로 이루어집니다.나는 장난감을 만들고 나서 색을 언급해야 한다.
function StarWarsFactory(){
  this.build = function(builder){
  builder.step1();
  builder.step2();
  return builder.getToy();
}}

function DarthVader_Builder(){
  this.darth = null;
  this.step1 = function () {
    this.darth = new DarthVader(); 
  }

  this.step2 = function () {
    this.darth.addColor();
  }

  this.getToy = function () {
    return this.darth;
  }
}

function DarthVader () {
  this.color = '';
  this.addColor = function(){
    this.color = 'black';
  }
  this.say = function () {
    console.log("I am Darth, and my color is "+this.color);
  }
}

function build(){
  let star_wars = new StarWarsFactory();
  let darthVader = new DarthVader_Builder();
  let darthVader_Toy = star_wars.build(darthVader);
  darthVader_Toy.say();
}

공장

공장의 역할은 동일한 특성을 가진 유사한 물체를 생산하는 것입니다.이를 통해 객체를 쉽게 관리, 유지 보수 및 조작할 수 있습니다.

 예를 들어, 우리 장난감 공장에서는 모든 장난감이 특정한 정보를 가지고 있을 것입니다. 구입일, 원산지, 카테고리 등이 기재되어 있습니다.

var ToyFactory = function(){
  this.createToy = function(type) 
  {
    var toy;
    if(type == "starwars")
      {
        toy = new StarWars();
      }
    toy.origin = "Origin";
    toy.dop = "2/22/2022";
    toy.category="fantasy";
  }
}

프로토타입

대부분의 경우 다른 부모 오브젝트의 기본값을 가진 새 오브젝트를 작성해야 합니다.그러면 초기화되지 않은 값을 가진 개체가 생성되지 않습니다. 프로토타입 패턴을 사용하여 이러한 객체를 만들 수 있습니다.

프로토타입 패턴은 특성 패턴(Properties Pattern)이라고도 합니다.

  1. 저희 장난감 공장에는 많은 캐릭터를 생산하는 스타워즈부가 있습니다.
  2. 각 캐릭터에는 장르, 만료일 및 상태 필드가 있습니다.이 필드는 스타워즈 부서의 모든 장난감에서 동일하게 유지됩니다.
function Star_Wars_Prototype(parent){
   this.parent = parent;
   this.duplicate = function () 
   {
      let starWars = new StarWarsToy();
      starWars.genre = parent.genre;
      starWars.expiry = parent.expiry;
      starWars.status = parent.status;
      return starWars;
   };
}

function StarWarsToy(genre, expiry, status){
   this.genre = genre;
   this.expiry = expiry;
   this.status = status;
}

function build () {
   var star_wars_toy = new StarWarsToy('fantasy', 'NA', 'Jan');
   var new_star_wars_toy = new Star_Wars_Prototype(star_wars_toy);
   
   //When you are ready to create
   var darth = new_star_wars_toy.duplicate();
}

싱글턴

싱글톤 패턴은 "싱글 인스턴스"에 해당합니다.지정된 개체는 단일 인스턴스만 가질 수 있습니다. 시스템에 단일 지점에서 조정해야 하는 데이터가 있는 경우 이 패턴을 사용할 수 있습니다.

var Singleton = (function () {
   var instance;

   function createInstance() {
       var object = new Object("I am the instance");
       return object;
   }

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

function run() {

   var instance1 = Singleton.getInstance();
   var instance2 = Singleton.getInstance();

   console.log("Same instance? " + (instance1 === instance2));
}

구조 설계 패턴 (Structural Design Patterns)

  1. 어댑터
  2. 다리(Bridge)
  3. 컴포지트
  4. 데코레이터
  5. 전면 (Facade)
  6. 플라이급(Flyweight)
  7. 프록시

어댑터

어댑터 설계 패턴은 개체의 속성 또는 메서드를 서로 변환해야 할 때 사용됩니다. 이 패턴은 인터페이스가 일치하지 않는 컴포넌트가 서로 동작해야 하는 경우에 매우 유용합니다. 어댑터 패턴은 래퍼 패턴이라고도 합니다.

Toy Factory를 통해 이 점을 이해합시다.

  1. 장난감 공장에는 배송부가 있습니다.
  2. 우리는 이전 배송 부서에서 새로운 부서로 이전할 예정입니다.
  3. 다만, 현재 재고가 있기 때문에, 이전의 배송 방법을 그대로 유지할 필요가 있습니다.
// old interface

function Shipping() {
    this.request = function (zipStart, zipEnd, weight) {
        // ...
        return "$49.75";
    }
}

// new interface

function AdvancedShipping() {
    this.login = function (credentials) { /* ... */ };
    this.setStart = function (start) { /* ... */ };
    this.setDestination = function (destination) { /* ... */ };
    this.calculate = function (weight) { return "$39.50"; };
}

// adapter interface

function ShippingAdapter(credentials) {
    var shipping = new AdvancedShipping();

    shipping.login(credentials);

    return {
        request: function (zipStart, zipEnd, weight) {
            shipping.setStart(zipStart);
            shipping.setDestination(zipEnd);
            return shipping.calculate(weight);
        }
    };
}

function run() {

    var shipping = new Shipping();
    var credentials = { token: "StarWars-001" };
    var adapter = new ShippingAdapter(credentials);

    // original shipping object and interface

    var cost = shipping.request("78701", "10010", "2 lbs");
    console.log("Old cost: " + cost);

    // new shipping object with adapted interface

    cost = adapter.request("78701", "10010", "2 lbs");

    console.log("New cost: " + cost);
}

다리(Bridge)

그 다리는 유명한 고급 건축 양식이다. 다양한 수준의 추상화를 제공함으로써 도움이 됩니다. 그 결과 오브젝트는 느슨하게 결합됩니다. 컴포넌트가 되는 모든 오브젝트에는 독자적인 인터페이스가 있습니다.

 

스타워즈 장난감을 생산하는 저희 장난감 공장에는 두 가지 종류가 있습니다. 한 세트의 장난감은 리모컨으로 조작할 수 있습니다. 또 다른 장난감 세트는 배터리를 사용하여 작동하며 다른 소리를 냅니다. 브리지 패턴은 이 고급 아키텍처를 구축하는 데 도움이 됩니다.

var Remote_Control = function (output) {
    this.output = output;
    this.left = function () { this.output.left(); }
    this.right = function () { this.output.right(); }
};

var Battery_Operation= function (output) {
    this.output = output;
    this.move = function () { this.output.move(); }
    this.wheel = function () { this.output.zoom(); }
};

var Remote_Controlled_Toy = function () {
    this.left = function () { console.log("Move Left"); }
    this.right = function () { console.log("Move Right"); }
};

var Battery_Operated_Toy = function () {
    this.move = function () { console.log("Sound waves"); }
    this.wheel = function () { console.log("Sound volume up"); }
};

function run() {

    var remote_control = new Remote_Control();
    var battery_operation = new Battery_Operation();
    var star_wars_type_1 = new Remote_Controlled_Toy(remote_control);
    var star_wars_type_2 = new Battery_Operated_Toy(battery_operation);
    star_wars_type_1.left();
    star_wars_type_2.wheel();
}

컴포지트

이름에서 알 수 있듯이 복합 패턴은 원시 개체 또는 개체의 집합인 개체를 생성합니다. 이렇게 하면 깊이 중첩된 구조를 구축하는 데 도움이 됩니다.

저희 완구 공장에서는 복합 패턴이 다음과 같은 방법으로 도움이 됩니다.

  1. 두 개의 부서가 있는데, 하나는 수동 부문이고, 두 개는 자동화 부문입니다.
  2. 매뉴얼 코너에는 장난감(잎)이 많이 있습니다.
  3. 자동화 코너에는 다른 장난감 세트(잎)가 있습니다.
var Node = function (name) {
    this.children = [];
    this.name = name;
}

Node.prototype = {
    add: function (child) {
        this.children.push(child);
    }
}

function run() {
    var tree = new Node("Star_Wars_Toys");
    var manual = new Node("Manual")
    var automate = new Node("Automated");
    var darth_vader = new Node("Darth Vader");
    var luke_skywalker = new Node("Luke Skywalker");
    var yoda = new Node("Yoda");
    var chewbacca = new Node("Chewbacca");

    tree.add(manual);
    tree.add(automate);

    manual.add(darth_vader);
    manual.add(luke_skywalker);

    automate.add(yoda);
    automate.add(chewbacca);

}

데코레이터

데코레이터 패턴은 오브젝트의 특성 및 메서드를 확장하여 런타임 동안 오브젝트에 새로운 동작을 추가합니다. 여러 개의 장식 기를 사용하여 객체의 실제 기능을 추가하거나 재정의할 수 있습니다.

저희 완구 공장에서는 완구에 이름을 붙이는 기능이 있습니다. 그리고 장르를 설명할 데코레이터가 하나 더 있다.

var Toy = function (name) {
    this.name = name;
    this.display = function () {
        console.log("Toy: " + this.name);
    };
}

var DecoratedToy = function (genre, branding) {
    this.toy = toy;
    this.name = user.name;  // ensures interface stays the same
    this.genre = genre;
    this.branding = branding;
    this.display = function () {
        console.log("Decorated User: " + this.name + ", " +
            this.genre + ", " + this.branding);
    };
}
function run() {
    var toy = new User("Toy");
    var decorated = new DecoratedToy(toy, "fantasy", "Star Wars");
    decorated.display();
}

전면(Facade)

파사드 디자인 패턴은 특성 및 메서드의 고급 인터페이스를 제공합니다. 이러한 속성과 메서드는 서브시스템에서 사용할 수 있습니다.

 

플라이급(Flyweight)

이 패턴은 객체 간에 객체를 공유해야 할 때 사용됩니다. 개체는 불변할 것입니다.

왜요? 오브젝트는 다른 사람이 공유하기 때문에 변경할 수 없습니다. Javascript 엔진에 Flyweight 패턴이 있습니다.

예를 들어 Javascript Engine은 애플리케이션 간에 공유할 수 있는 불변 문자열 목록을 유지합니다.

 

장난감 공장:

  1. 모든 장난감에는 장르가 있다.
  2. 모든 장난감에는 제조국이 있다.
  3. 모든 장난감에는 제조 년수가 있습니다. 이러한 속성은 Flyweight 모델에서 유지할 수 있습니다.
function Flyweight(genre, country, year) {
    this.genre = genre;
    this.country = country;
    this.year = year;
};

var FlyWeightFactory = (function () {
    var flyweights = {};
    return {
        get: function (genre, country, year) {
            if (!flyweights[genre + country]) {
                flyweights[genre + country] =
                    new Flyweight(genre, country, year);
            }
            return flyweights[genre + country];
        }
    }
})();

function ToyCollection() {
    var toys = {};
    return {
        add: function (genre, country, year, brandTag) {
            toys[brandTag] =
                new Toy(genre, country, year, brandTag);
        }
    };
}

var Toy = function (genre, country, year, brandTag) {
    this.flyweight = FlyWeightFactory.get(genre, country, year, brandTag);
    this.brandTag = brandTag;
 }
function build() {
    var toys = new ToyCollection();
    toys.add("Fantasy", "USA", "2021", "StarWars_01");
    toys.add("Fantasy", "USA", "2021", "Transformers_01");
}

프록시

프락시 패턴은 실제 개체 대신 자리 표시자 개체를 제공합니다. 자리 표시자 개체는 실제 개체 값에 대한 액세스를 제어합니다.

예를 들어, 저희 장난감 공장은 세계 여러 곳에 위치하고 있습니다. 모든 곳에서 많은 장난감을 생산한다. 프락시 패턴을 사용하면 각 위치에서 얼마나 많은 장난감이 생산되는지 쉽게 파악할 수 있습니다.

function GeoCoder() {
    this.getLatLng = function (address) {
        if (address === "Hong Kong") {
            return "52.3700° N, 4.8900° E";
        } else if (address === "North America") {
            return "51.5171° N, 0.1062° W";
        } ….    };
}
function GeoProxy() {
    var coder = new GeoCoder();
    var geoCollector = {};
    return {
        getLatLng: function (location) {
            if (!geoCollector[location]) {
                geoCollector[location] = coder.getLatLng(location);
            }
            return geoCollector[location];
        }};
};
function run() {
    var geo = new GeoProxy();
    geo.getLatLng("Hong Kong");
    geo.getLatLng("North America"); 
}

동작 설계 패턴 (Behavioral Design Patterns)

  1. 책임의 연속(Chain of Responsibility)
  2. 명령어
  3. 통역사 (Interpreter)
  4. 반복기 (Iterator)
  5. 중개자 (Mediator)
  6. 기념품 (Memento)
  7. 옵서버 (Observer)
  8. 스테이트 (State)
  9. 전략 (Strategy)
  10. 템플릿
  11. 방문자 (Visitor)

책임의 연속

Javascript를 사용하는 사람이라면 이벤트 버블링이라는 개념을 한 번쯤은 접했을 것이다. 여기서 이벤트가 중첩된 컨트롤 간에 전파됩니다. 컨트롤 중 하나가 버블링 이벤트를 처리하도록 선택할 수 있습니다. 책임 사슬 패턴을 사용하여 이 동작을 처리할 수 있습니다. 정확히 말하면 이 패턴은 JQuery에서 널리 사용되고 있습니다. 명령

 

명령어

대부분의 경우 오브젝트에는 처리할 공통 이벤트 세트가 있습니다.명령 개체는 이러한 이벤트를 처리하기 위한 작업을 캡슐화할 수 있는 개체를 구축하는 데 도움이 됩니다.대부분의 경우 명령 패턴은 기능을 중앙 집중화하는 데 사용됩니다.예를 들어 응용 프로그램의 실행 취소 조작은 명령 패턴의 예입니다.메뉴 드롭다운에서 호출하든 키보드에서 호출하든 동일한 기능이 호출됩니다.

 

통역사 (Interpreter)

모든 솔루션이 동일한 것은 아닙니다.많은 응용 프로그램에서는 사용자에게 표시되는 입력 또는 출력을 조작하기 위해 코드 행을 추가해야 할 수 있습니다.여기서 출력은 어플리케이션에 따라 달라집니다.

 

우리의 장난감 공장 예에서는 모든 스타워즈 장난감 앞에 "May the Force be with You"라는 태그 라인을 붙여야 합니다.그리고 모든 Bob the Builder 장난감에는 "Are you Ready!"라는 접두사가 붙어야 합니다.인터프리터 패턴을 사용하여 이 추가 수준의 커스터마이즈를 수행할 수 있습니다.

var Prefix = function (brandTag) {
    this.brandTag = brandTag;
}

Prefix.prototype = {
    interpret: function () {
        if (this.brandTag  == “Star Wars”) {
            return “May the Force be with You”;
        }
        else if (this.brandTag  == “Bob the Builder”) {
            return “Are you Ready?”;        
        }
    }
}

function run() {
    var toys = [];
    toys.push(new Prefix(“Star Wars”));
    toys.push(new Prefix(“Bob the Builder”));
    for (var i = 0, len = toys.length; i < len; i++) {
        console.log(toys[i].interpret());
    }
}

반복기 (Iterator)

 

이름에서 알 수 있듯이 반복 패턴을 사용하여 개체 또는 개체 집합을 효과적으로 루프하는 방법을 정의할 수 있습니다.J avascript에서는 몇 가지 일반적인 루프 형태를 볼 수 있습니다: while, for, for-in, and do while.반복기 패턴을 사용하면 작성된 애플리케이션에 맞게 유연하게 객체를 루프하는 자신만의 방법을 설계할 수 있습니다.

 

중개자 (Mediator)

이름 그대로 작동하는 또 다른 디자인 패턴은 중재자입니다.이 패턴은 객체 그룹에 대한 중앙 제어 지점을 제공합니다.상태 관리를 수행하기 위해 많이 사용됩니다.오브젝트 중 하나가 속성 상태를 변경하면 다른 오브젝트에 쉽게 브로드캐스트할 수 있습니다.

다음은 Mediator 설계 패턴이 어떻게 도움이 되는지 보여주는 간단한 예입니다.

var Participant = function (name) {
    this.name = name;
    this.chatroom = null;
}
//define a Itprototype for participants with receive and send implementation
var Talkie = function () {
    var participants = {};
    return {
       register: function (participant) {
            participants[participant.name] = participant;
            participant.talkie = this;
        },
        send: function (message, from, to) {
            if (to) {                      // single message
                to.receive(message, from);
            } else {                       // broadcast message
                for (key in participants) {
                    if (participants[key] !== from) {
                        participants[key].receive(message, from);
                    }
                }
            }
        }
    };
};

function letsTalk() {
    var A = new Participant("A");
    var B = new Participant("B");
    var C = new Participant("C");
    var D = new Participant("D");
    var talkie = new Talkie();
    talkie.register(A);
    talkie.register(B);
    talkie.register(C);
    talkie.register(D);
    A.send("I love you B.");
    B.send("No need to broadcast", A);
    C.send("Ha, I heard that!");
    D.send("C, do you have something to say?", C);
}

기념품(Memento)

Memento는 개체의 상태가 저장되는 저장소를 나타냅니다.

응용 프로그램에서 개체 상태를 저장하고 복원해야 하는 시나리오가 있을 수 있습니다.대부분의 경우 JSON을 사용한 객체의 직렬화 및 직렬화 해제 속성이 이 설계 패턴을 구현하는 데 도움이 됩니다.

var Toy = function (name, country, year) {
    this.name = name;
    this.country = country;
    this.city = city;
    this.year = year;
}

Toy.prototype = {
    encryptLabel: function () {
        var memento = JSON.stringify(this);
        return memento;
    },

    decryptLabel: function (memento) {
        var m = JSON.parse(memento);
        this.name = m.name;
        this.country = m.country;
        this.city = m.city;
        this.year = m.year;
        console.log(m);
    }
}

function print() {
    var darth = new Toy("Darth Vader", "USA", "2022");
    darth.encryptLabel();
    darth.decryptLabel();
}

옵저버 (Observer)

 

옵저버 패턴은 가장 널리 사용되는 패턴 중 하나입니다.Angular 및 React와 같은 플랫폼 전체에서 고유한 구현을 제공합니다.사실, 그것은 그 자체로 논의되어야 할 주제이다.

그럼에도 불구하고 이 패턴은 구독 모델을 제공합니다.오브젝트는 특정 이벤트를 서브스크라이브할 수 있습니다.그리고, 이벤트가 발생하면, 그들에게 통지할 것입니다.JavaScript는 이벤트 기반 프로그래밍 언어입니다.개념의 대부분은 옵저버 패턴에 의존합니다.

 

스테이트(State)

예를 들어 보겠습니다. 교통신호는 빨간색, 주황색, 녹색의 3가지 색상이 있습니다.수행할 작업은 색상에 따라 다릅니다.즉, 색상 고유의 논리가 있습니다.색상의 모든 물체는 색상의 규칙을 준수해야 합니다.마찬가지로 상태 패턴에는 모든 상태에 대한 특정 논리 집합이 포함되어 있습니다.상태 내의 개체는 이 논리를 따라야 합니다.

 

전략 (Strategy)

Strategy Design Pattern은 알고리즘을 캡슐화하기 위해 사용됩니다.알고리즘은 특정 작업을 완료하는 데 사용할 수 있습니다.실행하는 실제 전략(일명 방식)은 특정 전제조건에 따라 달라집니다.즉, 전략 내에서 사용되는 알고리즘은 호환성이 매우 높다는 것을 의미합니다.

완구 공장에서는, 3개의 다른 회사를 사용해 제품을 출하하고 있습니다.FedEx, USPS 및 UPS.최종 배송비는 회사에 따라 다릅니다.따라서 전략 설계 패턴을 사용하여 최종 비용을 결정할 수 있습니다.

Distributor.prototype = {
    setDistributor: function (company) {
        this.company = company;
    },

    computeFinalCost: function () {
        return this.company.compute();
    }
};

var UPS = function () {
    this.compute = function () {
        return "$45.95";
    }
};

var USPS = function () {
    this.compute = function () {
        return "$39.40";
    }
};

var Fedex = function () {
    this.compute = function () {
        return "$43.20";
    }
};

function run() {
    var ups = new UPS();
    var usps = new USPS();
    var fedex = new Fedex();
    var distributor = new Distributor();
    distributor.setDistributor(ups);
    console.log("UPS Strategy: " + distributor.computeFinalCost());
    distributor.setDistributor(usps);
    console.log("USPS Strategy: " + distributor.computeFinalCost());
    distributor.setDistributor(fedex);
    console.log("Fedex Strategy: " + distributor.computeFinalCost());
}

템플릿 (Template)

 

Template Pattern(템플릿 패턴)은 스텝 아웃룩을 나타냅니다.이 패턴에 대해 오브젝트가 생성되면 템플릿의 모든 단계를 완료해야 합니다.물론 스텝은 작성된 오브젝트에 맞게 커스터마이즈할 수 있습니다.이 설계 패턴은 공통 라이브러리와 프레임워크에서 널리 사용됩니다.

 

방문자 (Visitor)

마지막으로 방문자 디자인 패턴입니다.개체 그룹에 대해 새 작업을 정의해야 할 때 유용합니다. 그러나 객체의 원래 구조는 그대로 남아 있어야 합니다.이 패턴은 프레임워크 또는 라이브러리를 확장해야 할 때 유용합니다.

 게시물에서 설명한 다른 패턴과 달리, 방문자 디자인 패턴은 Javascript에서 널리 사용되지 않습니다. 왜일까요? JavaScript 엔진은 객체에서 동적으로 속성을 추가하거나 제거할 수 있는 보다 진보되고 유연한 방법을 제공합니다.

var Employee = function (name, salary, vacation) {
    var self = this;

    this.accept = function (visitor) {
        visitor.visit(self);
    };
  this.getSalary = function () {
        return salary;
    };
    this.setSalary = function (salary) {
        salary = salary;
    };
};

var ExtraSalary = function () {
    this.visit = function (emp) {
        emp.setSalary(emp.getSalary() * 2);
    };
};

function run() {
    var john = new Employee("John", 10000, 10),
    var visitorSalary = new ExtraSalary();
    john.accept(visitorSalary);
    }
}

결론

일부 디자인 패턴은 Javascript 엔진에 자주 사용됩니다.그리고 우리 중 많은 사람들은 이 패턴들이 사용되고 있는지조차 모른다.패턴을 사용하면 코드의 성능과 유지보수가 향상됩니다.이것이 바로 코드에 더 많은 패턴을 사용해야 하는 이유입니다.코드에 패턴을 도입하는 과정은 하룻밤에 끝날 필요는 없습니다.대신 패턴을 학습하고 점차 응용 프로그램에 포함시키십시오.