싱글톤 패턴(Singleton Pattern)
// class object example
class Cat {
constructor(name) {
this.name = name
}
speak() {
console.log(this.name, 'meow')
}
}
let kitty = new Cat('kitty')
let nabi = new Cat('nabi')
if(kitty === nabi) {
cosole.log('they are same')
} else {
console.log('they are not same')
}
// 결과: they are not same
// class의 인스턴스로 kitty와 nabi가 생성이 되고 서로 다른 오브젝트로 할당
// singleton example
class SingleCat {
static instance;
constructor(name) {
this.name = name
if(!SingleCat.instance) {
SingleCat.instance = this;
}
return SingleCat.instance
}
speak() {
console.log(this.name, 'meow')
}
}
let sKitty = new SingleCat('kitty')
let sNabi = new SingleCat('nabi')
if(sKitty === sNabi) {
console.log('they are same, Singleton')
} else {
console.log('they are not same')
}
// 결과: they are same, Singleton
// sNabi instanceof SingleCat --> True
// sKitty instanceof SingleCat --> True
// 하지만 이미 만들어진 sKitty 인스턴스로 인해서 sKitty, sNabi 둘다 sKitty를 가르키고 있음.
팩토리 메소트 (Factory Method Pattern)
public abstract class NotBook {
public abstract String getName();
}
public class Apple extends NotBook {
@Override
public String getName() {
return "Apple NotBook";
}
}
public class Samsung extends Notebook {
@Override
public String getName() {
return "Samsung NotBook";
}
}
// NotBook 의 생성을 담당하는 Factory 클래스 생성
public class NotBookFactory {
NotBook createNotBook(String name) {
switch( name ){
case "Apple": return new Apple();
case "Samsung": return new Samsung();
}
return null;
}
}
// 인터페이스를 제공
// 오브젝트를 팩토리의 메소드를 통해서 만들어낸다.
//메인 프로그램은 어떤 객체가 생성 되었는지 신경 쓰지 않고 단지 반환된 객체를 사용만 하면 됨
public class FactoryMain {
public static void main(String[] args) {
CarFactory cf = new CarFactory();
NotBook r = cf.NotBookFactory("Apple");
NotBook r2 = cf.NotBookFactory ("Samsung");
System.out.println(r.getName());
System.out.println(r2.getName());
}
}
전략 팩토리 (Strategy Factory)
class AuthStrategy {
auth() {
throw new Error('auth() must be implement')
}
}
class OAuth extends AuthStrategy {
auth() {
console.log('Authenticating using OAuth Strategy')
}
}
class Basic extends AuthStrategy {
auth() {
console.log('Authenticating using Basic Strategy')
}
}
class OAuth2 extends AuthStrategy {
auth() {
console.log('Authenticating using OAuth2 Strategy')
}
}
class AuthProgram {
constructor(authStrategy) {
this._authStrategy = authStrategy;
}
authenticate() {
if(!this._authStrategy) {
console.log('No Authentication Strategy set.')
return
}
this._authStrategy.auth()
}
}
// 📌 AuthProgram: 인증진행을 위한 절차를 구현한다. 필요한 인증방식 객테를 인자로 주입한다.
// 📌 AuthStrategy: 제공하는 모든 Auth 알고리즘에 대한 공통의 연산들을 정의한다.
// 📌 OAuth, OAuth2, Basic: AuthStrategy를 각각의 실제 Auth 알고리즘으로 구현한다.
const authProgram = new AuthProgram(new Basic())
authProgram.authenticate()
AuthProgram에서는 사용하는 각각의 인증방식이 내부적으로 어떻게 구현되어있는지 몰라도 된다. 그저 사용자가 선택한 AuthStrategy의 공통된 사용방법만 알고 있으면 된다.