
디자인 패턴 : 프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 '규약'으로 만들어 놓은 것
하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴. 보통 데이터베이스 연결 모듈에 많이 사용된다
class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return singleInstanceHolder.INSTANCE;
}
}
public class HelloWorld {
public static void main(String[] args) {
Singleton a = Singleton.getInstance();
Singleton b = Singleton.getInstance();
if(a==b) System.out.println(true);
}
}
// a==b이므로 true가 반환된다
객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴.
상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴.
enum coffeeType {
LATTE,
ESPRESSO
}
abstract class Coffee {
protected String name;
public String getName() {return name;}
}
class Latte extends Coffee {
public Latte {name = "latte";}
}
class Espresso extends Coffee {
public Espresso{name="espresso";}
}
class CoffeeFactory {
public static Coffee createCoffee(CoffeeType type) {
switch(type) {
case LATTE: return new Latte();
ase Espresso: return new Espresso();
default: throw newe IllegalArgumentException("invalid coffee type: " + type);
}
}
}
public class Main {
public static void main(String[] args) {
Coffee coffee = CoffeeFactory.createCoffee(CoffeeType.LATTE);
System.out.println(coffee.getName()); // latte
}
}
객체의 행위를 바꾸고 싶은 경우 직접 수정하지 않고, '캡슐화된 알고리즘'을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴

어떤 아이템을 살 때 LUNA Card로 사는 것과 KAKAOCard로 사는 것을 구현한 예제
interface PaymentStrategy{public void pay(int amount);}
class KAKAOCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public KAKAOCardStrategy(String name, String cardNumber, String cvv, String dayOfExpity){
this.name = name;
this.cardNumber = cardNumber;
this.cvv = cvv;
this.dayOfExpity = dayOfExpity;
}
@Override
public void pay(int amount) {System.out.println(amount + " paid usind KAKAOCard";}
}
class LUNACardStrategy implements PaymentStrategy {
private String emailId;
private String password;
public LUNACardStrategy(String email, String password) {
this.emailId = emailId;
this.password = password;
}
@Override
public void pay(int amount) {System.out.println(amount + " paid using LUNACard");}
}
전략 패턴을 활용한 라이브러리는 passport가 있다.

-> Node.js에서 인증 모듈을 구현할 때 쓰는 미들웨어 라이브러리로, 서비스 내 회원가입 방법과 페이스북/네이버 등 OAuth전략 등을 지원한다
주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴.
예시로는 트위터가 있다.

내가 어떤 사람인 주체를 '팔로워'한 상태라면, 주체가 포스팅을 올릴 때마다 알람이 '팔로워'에게 전달되야 한다
또한, 주로 이벤트 기반 시스템이나 MVC패턴에도 사용된다(주체인 model에 변경사항이 생겨 update()메서드로 옵저버인 view에 알려주고, 이를 기반으로 controller가 동작하는 방식)

interface Subject{
public void register(Observer obj);
public void unregister(Observer obj);
public void notifyObservers();
public Object getUpdate(Observer obj);
}
interface Observer {
public void update();
}
class Topic implements Subject {
private List<Observer> observers;
private String message;
public Topic() {
this.observers = observers;
this.message = "";
}
@Override
public void register(Observer obj) {
if(!observers.contain(obj)) observers.add(obj);
}
@Override
public void unregister(Observer obj) {
observers.remove(obj)
}
@Override
public void notifyObservers() {
this.observers.forEach(Observer::update);
}
@Override
public void getUpdate(Observer obj) {
return this.message;
}
public void postMessage(String msg) {
this.message = msg;
notifyObservers();
}
}
class TopicSubscriber implements Observer {
private String name;
private Subject topic;
public TopicSubscriber(String name, Subject topic) {
this.name = name;
this.topic = topic;
}
@Override
public void update() {
String msg = String.valueOf(topic.getUpdate(this));
}
}