프로그램 설계 시 발생했던 문제점들을객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 ‘규약’ 형태로 만들어 놓은 것
하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
보통 데이터베이스 연결 모듈에 많이 사용
장점 : 인스턴스 생성 시 드는 비용 감소 → 메모리 절약
단점 : 의존성이 증가
class Singleton {
constructor() {
if (!Singleton.instance) {
Singleton.instance = this;
}
return Singleton.instance;
}
getInstance() {
return this;
}
}
const a = new Singleton();
const b = new Singleton();
console.log(a === b); // true
TDD(Test Driven Development) 시 걸림돌!
TDD → 서로 독립적이고 어떤 순서로도 실행 가능해야하는 단위 테스트
테스트마다 ‘독립적인’ 인스턴스 만들기 어렵다.
모듈간의 강한 결합 → 의존성 주입(DI, Dependency Injection)으로 느슨하게
의존성 == 종속성
의존성을 주입해서 의존성이 떨어진다. == 디커플링이 된다.
의존성 주입의 장점
객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴
상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정, 하위클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴
상위 하위 클래스 분리 → 느슨한 결합, 더 많은 유연성
객체 생성 로직 분리 → 유지 보수성 증가
class Latte {
constructor() {
this.name = 'latte';
}
}
class Espresso {
constructor() {
this.name = 'Espresso';
}
}
//2. 하위 클래스 LatteFactory -> 구체적인 내용을 결정
class LatteFactory {
static createCoffee() {
return new Latte();
}
}
class EspressoFactory {
static createCoffee() {
return new Espresso();
}
}
const factoryList = { LatteFactory, EspressoFactory };
//1. 상위 클래스 CoffeeFactory -> 중요한 뼈대를 결정
class CoffeeFactory {
static createCoffee(type) {
const factory = factoryList[type];
return factory.createCoffee();
}
}
const main = () => {
// 라떼 커피를 주문한다.
const coffee = CoffeeFactory.createCoffee('LatteFactory');
// 커피 이름을 부른다.
console.log(coffee.name); // latte
};
main();
상위 클래스 CoffeeFactory -> 중요한 뼈대를 결정
하위 클래스 LatteFactory -> 구체적인 내용을 결정
→ 의존성 주입
static
== 정책패턴 (Policy pattern)
객체의 행위를 바꾸고 싶은 경우 ‘직접’ 수정하지 않고 전략이라고 부르는 ‘캡슐화한 알고리즘’을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴
Node.js 인증 모듈 구현 미들웨어 라이브러리
여러 가지 ‘전략’을 기반으로 인증 가능하게 함
LocalStrategy 전략 - 서비스 내 회원가입 된 아이디,비밀번호 기반 인증
OAuth 전략 - 페이스북, 네이버 등 다른 서비스 기반 인증
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
//메소서드에 '전략' 매개변수
passport.use(
new LocalStrategy(function (username, password, done) {
User.findOne({ username: username }, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
})
);
passport.use() 메서드에 ‘전략’을 매개변수로 넣어 로직 수행
주체가 객체(subject)의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버들에게 변화를 알려주는 패턴
객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고, 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의한다.
객체 주체 분리되어 있는 옵저버 패턴, 객체+주체 옵저버 패턴
유튜버 - 주제(subject)
구독자 - 옵저버(observer)

주체 - model
옵저버 - view
model 변경 → update() 메서드로 옵저버인 view에 전달 → controller 작동

프록시 객체를 통해 구현한다.
프록시(proxy) 객체
어떠한 대상의 기본적인 동작의 작업을 가로챌 수 있는 객체
두 개의 매개변수를 가짐
프록시(proxy) 활용
function createReactiveObject(target, callback) {
const proxy = new Proxy(target, {
set(obj, prop, value) {
if (value !== obj[prop]) {
const prev = obj[prop];
obj[prop] = value;
callback(`${prop}가 [${prev}] >> [${value}] 로 변경되었습니다`);
}
return true;
},
});
return proxy;
}
const a = {
형규: '솔로',
};
const b = createReactiveObject(a, console.log);
b.형규 = '솔로';
b.형규 = '커플';
// 형규가 [솔로] >> [커플] 로 변경되었습니다
set() 메서드로 형규의 속성을 가로채서 솔로→ 커플로 감시 가능
대상 객체(subject)에 접근하기 전 그 접근에 대한 흐름을 가로채 대상 객체 앞단의 인터페이스 역할을 하는 패턴
객체의 속성, 변환 등 보완
데이터 검증, 캐싱, 로깅에 사용
서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램
비동기 이벤트 기반의 구조와 다수의 연결을 효과적으로 처리하는 웹 서버
Node.js 서버 구축 시 앞단에 nginx를 두어 보안성 강화, 버퍼 오버플로우 취약점 예방 가능

전 세계적 분산된 서버를 통한 시스템 콘텐츠 전달 빠르게 하는 CDN 서비스
웹 서버 앞단에 CloudFlare을 두면
Cross-Origin Resource Sharing(CORS) : 서버가 웹 브라우저에 리소스를 로드할 때 다른 오리진을 통해 로드하지 못하게 하는 HTTP 헤더 기반 메커니즘


면접을 위한 CS 전공지식 노트 - 주홍철
참고 블로그