JavaScript Design Patterns edward - Lee-hyuna/33-js-concepts-kr GitHub Wiki
JavaScript Design Patterns
Constructor Pattern μμ±μ ν¨ν΄
μ ν΅μ μΈ κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μ μμ΄μ μμ±μ(constructor)λ νΉλ³ν λ©μλλ‘ μλ‘κ² μμ±ν κ°μ²΄μ μ΄κΈ°νμ μ¬μ©λκ³ νλ² μμ±λ κ°μ²΄λ λ©λͺ¨λ¦¬μμ μ μ₯μ΄λ©λλ€. μλ°μ€ν¬λ¦½νΈμμλ κ±°μ λͺ¨λ κ²μ΄ κ°μ²΄μ΄κΈ°μ κ°μ²΄ μμ±μμ λλΆλΆμ κ΄μ¬μ κ°μ§κ² λ©λλ€.
κ°μ²΄ μμ±μλ κ°μ²΄λ₯Ό μ¬μ©ν μ€λΉλ₯Όνκ³ κ°μ²΄λ₯Ό μ²μ μμ± ν λ μμ±μμμ λ©€λ² μμ± λ° λ©μλ κ°μ μ€μ νλ λ° μ¬μ©ν μμλ μΈμλ₯Ό λ°μλ€μ΄λ νΉμ μ νμ κ°μ²΄λ₯Ό λ§λλ λ° μ¬μ©λ©λλ€.
1. Object Creation
κ°μ₯ μΌλ°μ μΈ κ°μΈ μμ±νλ λ°©λ²
2. Basic Constructors
function person(firstName,lastName){
this.firstName = firstName;
this.lastName = lastName;
this.fullName = function(){
return this.firstName + " " + this.lastName;
}
}
var person1 = new person('Akash','Pal');
var person2 = new person('Black','Panther');
person1.fullName(); //"Akash Pal"
person2.fullName(); //"Black Panther"
person1 //{firstName: "Akash", lastName: "Pal", fullName: Ζ}
person2 //{firstName: "Black", lastName: "Panther", fullName: Ζ}
3. Constructor with prototypes.
Module Pattern λͺ¨λ ν¨ν΄
μΌλ°μ μΌλ‘ λͺ¨λ ν¨ν΄μ μλ κΈ°μ‘΄μ μννΈμ¨μ΄ μμ§λμ΄λ§μμ ν΄λμ€μ λν private κ³Ό publicν μΊ‘μνλ₯Ό μ 곡νλ λ°©λ²μΌλ‘ μ μλμμ΅λλ€.
μλ°μ€ν¬λ¦½νΈμμ λͺ¨λ ν¨ν΄μ λ¨μΌ κ°μ²΄ λ΄μ 곡κ°/λΉκ³΅κ° λ©μλμ λ³μλ₯Ό λͺ¨λ ν¬ν¨ν μ μλλ‘ ν΄λμ€ κ°λ μ λμ± λͺ¨λ°©νμ¬ νΉμ λΆλΆμ κΈλ‘λ² λ²μμμ μ°¨λ¨νλ λ° μ¬μ©λ©λλ€. μ΄ κ²°κ³Ό νμ΄μ§μ μΆκ° μ€ν¬λ¦½νΈμ μ μλ λ€λ₯Έ ν¨μμ μΆ©λν κ°λ₯μ±μ΄ κ°μν©λλ€.
var personModule = (function(){
var firstName;
var lastName;
return{
setName(f,l){
firstName = f;
lastName = l;
},
getName(){
return firstName + " " + lastName;
}
}
})();
personModule.setName('akash','pal')
personModule.getName() //"akash pal"
Revealing Module Pattern λͺ¨λ λ ΈμΆ ν¨ν΄
κ°μΈ λ²μμμ λͺ¨λ ν¨μμ λ³μλ₯Ό κ°λ¨νκ² μ μνκ³ κ³΅κ°νκ³ μνλ κ°μΈ κΈ°λ₯μ λν ν¬μΈν°κ° μλ μ΅λͺ κ°μ²΄λ₯Ό λ°ννλ μ λ°μ΄νΈ λ ν¨ν΄μ λλ€.
var personModule = (function(){
var firstName;
var lastName;
function setName(f,l){
firstName = f;
lastName = l;
}
function getName(){
return firstName + " " + lastName;
}
return{
setName:setName,
getName:getName
}
})();
personModule.setName('akash','pal');
personModule.getName(); //"akash pal"
Singleton Pattern μ±κΈν€ ν¨ν΄
μ±κΈν€ ν¨ν΄μ ν΄λμ€μ μΈμ€ν΄μ€νλ₯Ό λ¨μΌ κ°μ²΄λ‘ μ ννκΈ° λλ¬Έμ μλ €μ Έ μμ΅λλ€. κ³ μ μ μΌλ‘ μ±κΈν€ ν¨ν΄μ΄ μ‘΄μ¬νμ§ μλ κ²½μ° ν΄λμ€μ μλ‘μ΄ μΈμ€ν΄μ€λ₯Ό μμ±νλ λ©μλλ‘ ν΄λμ€λ₯Ό μμ±νμ¬ κ΅¬νν μ μμ΅λλ€. μΈμ€ν΄μ€κ° μ΄λ―Έ μ‘΄μ¬νλ κ²½μ° ν΄λΉ κ°μ²΄μ λν μ°Έμ‘°λ₯Ό λ°νν©λλ€.
var singleton = (function(){
var instance;
function init(){
var name;
this.setName = function(name){
this.name = name;
}
this.getName = function(){
return this.name;
}
return{
setName:setName,
getName:getName
}
}
function getInstance(){
if(!instance){
instance = init();
}
return instance;
}
return{
getInstance:getInstance
}
})();
var one = singleton.getInstance();
var two = singleton.getInstance();
//the two instance are same
one == two //true
one.setName('Akash');
two.getName(); //"Akash"
Observer Pattern μ΅μ Έλ² ν¨ν΄
μ΅μ λ²λ κ°μ²΄(μ£Όμ²΄λ‘ μλ €μ Έ μμ)κ° κ°μ²΄(κ΄μ°°μ)μ λ°λΌ κ°μ²΄ λͺ©λ‘μ μ μ§νκ³ μν λ³κ²½μ μλμΌλ‘ μλ €μ£Όλ λμμΈ ν¨ν΄μ λλ€.
-
Subject: κ΄μ°°μ λͺ©λ‘μ μ μ§νκ³ κ΄μ°°μ μΆκ° λλ μ κ±°λ₯Ό μ©μ΄νκ² ν©λλ€.
-
Observer: λμμ μν λ³κ²½μ μ릴 νμκ° μλ κ°μ²΄μ λν μ λ°μ΄νΈ μΈν°νμ΄μ€λ₯Ό μ 곡ν©λλ€.
-
ConcreteSubject: μν λ³νμ λν κ΄μ°°μμκ² μλ¦Όμ μλ¦¬κ³ , ConcreteObserversμ μνλ₯Ό μ μ₯ν©λλ€.
-
ConcreteObserver: ConcreteSubjectμ λν μ°Έμ‘°λ₯Ό μ μ₯νκ³ μνκ° μ£Όμ μ μΌμΉνλλ‘ κ΄μ°°μμ λν μ λ°μ΄νΈ μΈν°νμ΄μ€λ₯Ό ꡬνν©λλ€.
Publish/Subscribe Pattern
μ΅μ Έμ ν¨ν΄μ μ£Όμ μλ¦Όμ μμ νλ €λ κ΄μ°°μ(λλ κ°μ²΄)κ° μ΄λ²€νΈλ₯Ό λ°μμν€λ κ°μ²΄(μ£Όμ )μ κ΄μ¬μ ꡬλ ν΄μΌν©λλ€.
κ·Έλ¬λ Publish/Subscribe ν¨ν΄μ μλ¦Όμ μμ νλ €λ κ°μ²΄(ꡬλ μ)μ μ΄λ²€νΈλ₯Ό λ°μμν€λ κ°μ²΄(κ²μμ) μ¬μ΄μμλ topic/event μ±λμ μ¬μ©ν©λλ€. μ΄ μ΄λ²€νΈ μμ€ν μ ν΅ν΄ μ½λλ κ°μ μκ° νμλ‘νλ κ°μ ν¬ν¨νλ μ¬μ©μ μ§μ μΈμλ₯Ό μ λ¬ν μμλ μμ© νλ‘κ·Έλ¨ νΉμ μ΄λ²€νΈλ₯Ό μ μ ν μ μμ΅λλ€. μ¬κΈ°μ μμ΄λμ΄λ ꡬλ μμ κ²μμ κ°μ μ’ μμ±μ νΌνλ κ²μ λλ€.
μ΄λ μ μ ν μ΄λ²€νΈ μ²λ¦¬κΈ°λ₯Ό ꡬννλ κ°μ μλ₯Ό κ²μμκ° λΈλ‘λ μΊμ€νΈ ν ν ν½ μλ¦Όμ λ±λ‘νκ³ μμ ν μμκ²νλ―λ‘ μ΅μ Έλ² ν¨ν΄κ³Ό λ€λ¦ λλ€.
μ΄λ―Έμ§ μ£Όμ : https://miro.medium.com/max/3028/1*-HzQOW37lYfr2HWQRPDHvw.png
Mediator Pattern
A Mediator is an object that coordinates interactions (logic and behavior) between multiple objects. It makes decisions on when to call which objects, based on the actions (or inaction) of other objects and input.
Prototype Pattern
νλ‘ν νμ
ν¨ν΄μ νλ‘ν νμ
μμμ κΈ°λ°μΌλ‘νκ³ λ€λ₯Έ κ°μ²΄μ νλ‘ν νμ
μΌλ‘ μλνλ κ°μ²΄λ₯Ό μμ±νλ κ²μΌλ‘ μκ°ν μ μμ΅λλ€.
νλ‘ν νμ
κ°μ²΄ μ체λ μμ±μκ° μμ±νλ κ° κ°μ²΄μ blueprint(μ²μ¬μ§)λ₯Ό ν¨κ³Όμ μΌλ‘ μ¬μ©λ©λλ€. μ¬μ©λ μμ±μ ν¨μμ νλ‘ν νμ
μ μλ₯Ό λ€λ©΄ μλμ μ½λ μνμ λ°λΌ name
μ΄λΌλ μμ±μ΄ ν¬ν¨ λ κ²½μ° λμΌν μμ±μμ μν΄ μμ± λ κ° κ°μ²΄μλ λμΌν μμ±μ΄ μμ΅λλ€.
ECMAScript 5 νμ€μ μ μ λ μ€μ νλ‘ν νμ
μμμλ Object.create
λ₯Ό μ¬μ©ν΄μΌν©λλ€.
function person(firstName,lastName){
this.firstName = firstName;
this.lastName = lastName;
}
person.prototype.fullName = function(){
return this.firstName + " " + this.lastName;
}
var person1 = new person('Akash','Pal');
var person2 = new person('Black','Panther');
person1 //{firstName: "Akash", lastName: "Pal"}
person2 //{firstName: "Black", lastName: "Panther"}
person1.fullName() //"Akash Pal"
person2.fullName() //"Black Panther"
Object.create
λ₯Ό μ§μ μ¬μ©νμ§ μλ νλ‘ν νμ
ν¨ν΄
Command Pattern
Command ν¨ν΄μ λ©μλ νΈμΆ, μμ² λλ μ€νΌλ μ΄μ μ λ¨μΌ μ€λΈμ νΈλ‘ μΊ‘μννλ λ° λͺ©μ μ΄ μμΌλ©° μ¬λμ λ°λΌ μ€νν μμλ λ©μλ νΈμΆμ λ§€κ° λ³μννκ³ μ λ¬ν μ μμ΅λλ€. λν μ‘μ μ ꡬννλ κ°μ²΄μμ μ‘μ μ νΈμΆνλ κ°μ²΄λ₯Ό λΆλ¦¬νμ¬ κ΅¬μ²΄μ μΈ ν΄λμ€(κ°μ²΄)λ₯Ό κ΅μ²΄ ν λ μ λ°μ μΈ μ μ°μ±μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€.
var name = {
fName:'aaa',
lName:'bbb',
setName:function(fName,lName){
this.fName = fName;
this.lName = lName;
},
getName:function(){
return this.fName + " " + this.lName;
}
}
name.execute = function(key){
var methodName = name[key];
var functionParamsArray = [].splice.call(arguments,1);
return methodName.apply(name,functionParamsArray);
}
name.execute('setName','Akash','Pal');
console.log(name.execute('getName'));//Akash Pal
Facade Pattern
Facadesλ jQueryμ κ°μ JavaScript λΌμ΄λΈλ¬λ¦¬μμ μ’ μ’ λ³Ό μμλ ꡬ쑰μ ν¨ν΄μ λλ€. ꡬνμ κ΄λ²μν λμμ κ°μ§ λ©μλλ₯Ό μ§μν μ μμ§λ§ μ΄λ¬ν λ©μλμ "facade(μ λ©΄)" λλ μ νλ μΆμνλ§ μ¬μ©μ μν΄ κ³΅κ°λ©λλ€.
Facadesλ λͺ¨λ ν¨ν΄κ³Ό κ°μ λ€λ₯Έ ν¨ν΄κ³Ό ν΅ν© λ μλ μμ΅λλ€.
Factory Pattern
ν©ν 리 ν¨ν΄μ κ°μ²΄ μμ± κ°λ κ³Ό κ΄λ ¨λ λ λ€λ₯Έ μμ± ν¨ν΄μ λλ€. μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ ν¨ν΄κ³Ό λ€λ₯Έ μ μ λͺ μ μ μΌλ‘ μμ±μλ₯Ό μ¬μ©ν νμκ° μλ€λ κ²μ λλ€. λμ ν©ν 리λ κ°μ²΄λ₯Ό μμ±νκΈ°μν μΌλ° μΈν°νμ΄μ€λ₯Ό μ 곡 ν μ μμΌλ©°, μ¬κΈ°μ μμ±νλ €λ ν©ν 리 κ°μ²΄μ μ νμ μ§μ ν μ μμ΅λλ€.
function Bike(options){
this.wheels = 2;
this.color = options.color;
}
function Car(options){
this.wheels = 4;
this.color = options.color;
}
function VehicleFactory(){}
VehicleFactory.prototype.createVehicle = function(options){
switch(options.type){
case 'Bike':
this.vehicleClass = Bike;
break;
case 'Car':
this.vehicleClass = Car;
break;
default:
this.vehicleClass = Bike;
}
return new this.vehicleClass(options);
}
var vehicleFactory = new VehicleFactory();
var bike = vehicleFactory.createVehicle({
type:'Bike',
color:'black'
});
console.log(bike); //Bike {wheels: 2, color: "black"}
var car = vehicleFactory.createVehicle({
type:'Car',
color:'white'
});
console.log(car); //Car {wheels: 4, color: "white"}
μ΄λ―Έμ§ μ£Όμ : https://miro.medium.com/max/2976/1*vS04c6QeLjIL_oj_pc0CHA.png
Mixin Pattern
Mixinsμ κΈ°λ₯ μ¬μ¬μ©μ μν΄ μλΈ ν΄λμ€ λλ μλΈ ν΄λμ€ κ·Έλ£Ήμ μν΄ μ½κ² μμ λ μμλ κΈ°λ₯μ μ 곡νλ ν΄λμ€μ λλ€.
function Person(firstName,lastName){
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullName = function(){
return this.firstName + " " + this.lastName;
}
function Superhero(firstName,lastName,powers){
//super call
Person.call(this,firstName,lastName);
this.powers = powers;
}
Superhero.prototype = new Object(Person.prototype);
Superhero.prototype.showPowers = function(){
return this.powers;
}
var superhero1 = new Superhero('Iron','Man',['Flying suit','Jarvis']);
console.log(superhero1.fullName() + '-' + superhero1.showPowers()); //Iron Man-Flying suit,Jarvis
var superhero2 = new Superhero('Captain','America',['strength','endurance','healing']);
console.log(superhero2.fullName() + '-' + superhero2.showPowers()); //Captain America-strength,endurance,healing