[디자인 패턴] 싱글톤, 팩토리, 전략 패턴

Chloe K·2023년 1월 11일
0
post-thumbnail

디자인 패턴

  • 소프트웨어를 설계할 때 자주 발생하는 고질적인 문제들이 또 발생했을 때 재사용할 수 있는 해결책
  • 패턴
    • 각기 다른 소프트웨어 모듈이나 기능을 가진 다양한 응용소프트웨어 시스템들을 개발할 때도 서로 간에 공통되는 설계 문제가 존재하며 이를 처리하는 해결책 사이에도 공톰점이 있다. 이러한 유사점을 패턴이라고 한다.
    • 패턴은 공통의 언어를 만들어주며 팀원 사이의 의사소통을 원할하게 해주는 중요한 역할을 한다.

디자인 패턴의 종류

GoF 디자인 패턴

  • Gang of Fout → 소프트웨어 개발 영역에서 디자인 패턴을 구체화하고 체계화한 사람들
  • 23가지의 디자인 패턴을 정리하고 각각의 디자인 패턴을 생성(Creational), 구조(Structural), 행위(Behavioral) 3가지로 분류했다.

생성 패턴(Creational Pattern)

싱글톤 패턴(Singleton Pattern)

  • 하나의 오브젝트만 생성이 되게 강제하는 패턴이다.
  • 즉 객체는 여러 번 생성되지 않고, 최초 하나의(Single) 인스턴스만 생성하고, 이후에는 이 인스턴스를 참조하게 된다.
// 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)

  • 인스턴스를 만들어내는 공장(Factory) 를 통해 객체를 생성하는 방법이다.
  • 인스턴스를 직접 생성해내지 않고, 공장에서 제공하는 메소드를 통해 생성해낸다.
  • 사용자는 객체를 생성하고 싶을 때, 공장에서 제공하는 메소드만 알고있으면 된다.
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());

 	}
 }

행동 패턴(Behavioral Patterns)

전략 팩토리 (Strategy Factory)

  • 동일 계열의 알고리즘군을 정의하고, 각각의 알고리즘을 캡슐화하여, 이들을 상호교환이 가능하도록 만드는 패턴이다.
  • 알고리즘을 사용하는 사용자와 상관없이 독립적으로 알고리즘을 다양하게 변경할 수 있게 한다.
  • 서로 다른 Strategy 클래스의 행동을 캡슐화하면 이들 조건문을 없앨 수 있다.
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의 공통된 사용방법만 알고 있으면 된다.

profile
Frontend Developer

0개의 댓글