-
Notifications
You must be signed in to change notification settings - Fork 13
JavaScript Design Patterns edward
Constructor Pattern 생성자 패턴
전통적인 객체지향 프로그래밍에 있어서 생성자(constructor)는 특별한 메서드로 새롭게 생성할 객체의 초기화에 사용되고 한번 생성된 객체는 메모리상에 저장이됩니다. 자바스크립트에서는 거의 모든 것이 객체이기에 객체 생성자에 대부분의 관심을 가지게 됩니다.
객체 생성자는 객체를 사용할 준비를하고 객체를 처음 생성 할 때 생성자에서 멤버 속성 및 메서드 값을 설정하는 데 사용할 수있는 인수를 받아들이는 특정 유형의 객체를 만드는 데 사용됩니다.
가장 일반적인 객세 생성하는 방법
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: ƒ}
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 패턴은 알림을 수신하려는 객체(구독자)와 이벤트를 발생시키는 객체(게시자) 사이에있는 topic/event 채널을 사용합니다. 이 이벤트 시스템을 통해 코드는 가입자가 필요로하는 값을 포함하는 사용자 지정 인수를 전달할 수있는 응용 프로그램 특정 이벤트를 정의 할 수 있습니다. 여기서 아이디어는 구독자와 게시자 간의 종속성을 피하는 것입니다.
이는 적절한 이벤트 처리기를 구현하는 가입자를 게시자가 브로드 캐스트 한 토픽 알림을 등록하고 수신 할 수있게하므로 옵져버 패턴과 다릅니다.
이미지 주소 : https://miro.medium.com/max/3028/1*-HzQOW37lYfr2HWQRPDHvw.png
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.
프로토타입 패턴은 프로토타입 상속을 기반으로하고 다른 객체의 프로토타입으로 작동하는 객체를 생성하는 것으로 생각할 수 있습니다.
프로토타입 객체 자체는 생성자가 생성하는 각 객체의 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 패턴은 메소드 호출, 요청 또는 오퍼레이션을 단일 오브젝트로 캡슐화하는 데 목적이 있으며 재량에 따라 실행할 수있는 메소드 호출을 매개 변수화하고 전달할 수 있습니다. 또한 액션을 구현하는 객체에서 액션을 호출하는 객체를 분리하여 구체적인 클래스(객체)를 교체 할 때 전반적인 유연성을 크게 향상시킬 수 있습니다.
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
Facades는 jQuery와 같은 JavaScript 라이브러리에서 종종 볼 수있는 구조적 패턴입니다. 구현은 광범위한 동작을 가진 메소드를 지원할 수 있지만 이러한 메소드의 "facade(정면)" 또는 제한된 추상화만 사용을 위해 공개됩니다.
Facades는 모듈 패턴과 같은 다른 패턴과 통합 될 수도 있습니다.
팩토리 패턴은 객체 생성 개념과 관련된 또 다른 생성 패턴입니다. 카테고리의 다른 패턴과 다른 점은 명시 적으로 생성자를 사용할 필요가 없다는 것입니다. 대신 팩토리는 객체를 생성하기위한 일반 인터페이스를 제공 할 수 있으며, 여기서 생성하려는 팩토리 객체의 유형을 지정할 수 있습니다.
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
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
일부 의역이 들어간 경우도 있으므로 해당 원문의 내용과 조금 다를 수 있습니다.
문제가 될 소지가 있다거나 혹은 수정이 필요한 사항이 있다면 있다면 issues 보내주세요.
기술문서
- 호출스택
- 원시자료형
- 값타입과 참조타입
- 명시적 변환, 암시적 변환, Nominal, 구조화, 덕 타이핑
- == vs === vs typeof
- 함수 범위, 블록 범위, 렉시컬(lexical) 범위
- 식(expression) vs 문(statement)
- IIFF, Modules, Namespaces
- 메세지큐와 이벤트루프
- setTimeout, setInterval, requestAnimationFrame
- 자바스크립트 엔진
- 비트 연산자, 형식화 배열, 버퍼(배열)
- DOM과 Layout Trees
- 팩토리와 클래스
- this, call, apply, bind
- new, 생성자, instanceof, 인스턴스
- 프로토타입의 상속과 체인
- Object.create와 Object.assign
- map, reduce, filter
- 순수함수, 부수효과, 상태변이
- Closure
- 고차함수
- 재귀
- 컬렉션과 생성기
- Promise
- async, await
- 자료구조
- 함수 성능과 빅 오 표기법
- 알고리즘
- 상속, 다형성, 코드의 재사용성
- 설계패턴
- 부분 어플리케이션, 커링, Compose, Pipe
- 클린코드