쉽게 말하면 프로그래밍을 설계할 때 자주 발생하는 오류들을 피하기 위해서 정해놓은 규약 이라고 의미한다.
디자인 패턴에 대해서 하나씩 알아보자
싱글톤 패턴은 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
즉, 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴임
자바에서의 싱글톤 패턴 예시
class Singleton {
static final Singleton instance = new Singleton();
private Singleton() {
//초기화
}
public static Singleton getInstance() {
return instance;
}
}
스프링 컨테이너는 싱글톤 패턴으로 객체를 만들지 않아도 알아서 객체 인스턴스를 싱글톤으로 관리함
싱글톤 객체는 상태를 stateful하게 설계하면 안되고 stateless하게 설계해야 함
팩토리 패턴은 객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴
즉, 상속관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴
전략 패턴은 객체의 행위를 바꾸고 싶은 경우 직접 수정하지 않고 전략이라는 부르는 캡슐화한 알고리즘을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴
// 전략(추상화된 알고리즘)
interface IStrategy {
void doSomething();
}
// 전략 알고리즘 A
class ConcreteStrateyA implements IStrategy {
public void doSomething() {}
}
// 전략 알고리즘 B
class ConcreteStrateyB implements IStrategy {
public void doSomething() {}
}
// 컨텍스트(전략 등록/실행)
class Context {
IStrategy Strategy; // 전략 인터페이스를 합성(composition)
// 전략 교체 메소드
void setStrategy(IStrategy Strategy) {
this.Strategy = Strategy;
}
// 전략 실행 메소드
void doSomething() {
this.Strategy.doSomething();
}
}
// 클라이언트(전략 교체/전략 실행한 결과를 얻음)
class Client {
public static void main(String[] args) {
// 1. 컨텍스트 생성
Context c = new Context();
// 2. 전략 설정
c.setStrategy(new ConcreteStrateyA());
// 3. 전략 실행
c.doSomething();
// 4. 다른 전략 설정
c.setStrategy(new ConcreteStrateyB());
// 5. 다른 전략 시행
c.doSomething();
}
}
옵저버 패턴은 주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴
자바에서의 옵저버 패턴
// 관찰 대상자 / 발행자
interface ISubject {
void registerObserver(IObserver o);
void removeObserver(IObserver o);
void notifyObserver();
}
class ConcreteSubject implements ISubject {
// 관찰자들을 등록하여 담는 리스트
List<IObserver> observers = new ArrayList<>();
// 관찰자를 리스트에 등록
@Override
public void registerObserver(IObserver o) {
observers.add(o);
System.out.println(o + " 구독 완료");
}
// 관찰자를 리스트에 제거
@Override
public void removeObserver(IObserver o) {
observers.remove(o);
System.out.println(o + " 구독 취소");
}
// 관찰자에게 이벤트 송신
@Override
public void notifyObserver() {
for(IObserver o : observers) { // 관찰자 리스트를 순회하며
o.update(); // 위임
}
}
}
// 관찰자 / 구독자
interface IObserver {
void update();
}
class ObserverA implements IObserver {
public void update() {
System.out.println("ObserverA 한테 이벤트 알림이 왔습니다.");
}
public String toString() { return "ObserverA"; }
}
class ObserverB implements IObserver {
public void update() {
System.out.println("ObserverB 한테 이벤트 알림이 왔습니다.");
}
public String toString() { return "ObserverB"; }
}
프록시 패턴은 대상 원본 객체를 대리하여 대신 처리하게 함으로써 로직의 흐름을 제어하는 행동 패턴
그냥 객체를 사용하지 않는 이유는, 해당 클래스에 민감한 정보가 포함되어 있거나, 추가 기능을 가미하고 싶을 때, 원본 객체를 수정할 수 없는 상황을 극복하기 위해 사용
자바에서의 프록시 패턴
interface ISubject {
void action();
}
class RealSubject implements ISubject {
public void action() {
System.out.println("원본 객체 액션 !!");
}
}
class Proxy implements ISubject {
private RealSubject subject; // 대상 객체를 composition
Proxy(RealSubject subject) {
this.subject = subject;
}
public void action() {
subject.action(); // 위임
/* do something */
System.out.println("프록시 객체 액션 !!");
}
}
class Client {
public static void main(String[] args) {
ISubject sub = new Proxy(new RealSubject());
sub.action();
}
}
서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용 프로그램 ( 예 : nginx)
nginx를 프록시 서버로 두면, 실제 포트를 숨길 수 있고 정적 자원을 gzip 압축하거나, 메인 서버 앞단에서의 로깅을 할 수 있음
이터레이터 패턴은 이터레이터를 사용하여 컬렉션의 요소들에 접근하는 디자인 패턴
노출모듈 패턴은 즉시 실행 함수를 통해 private, public 같은 접근 제어자를 만드는 패턴
자바 스크립트에서는 접근제어자가 존재하지 않고 전역 범위에서 스크립트가 실행되기 때문에 노출모듈 패턴을 이용해 private와 public 접근 제어자를 구현
모델, 뷰, 컨트롤러로 이루어진 디자인 패턴
모델은 어플리케이션의 데이터인 데이터베이스, 상수, 변수 등을 뜻함
뷰는 inputbox, checkbox, textarea 등 사용자 인터페이스 요소를 나타냄. 즉, 모델을 기반으로 사용자가 볼 수 있는 화면
컨트롤러는 하나 이상의 모델과 하나 이상의 뷰를 잇는 다리 역할을 하며 이벤트 등 메인 로직을 담당.
또한 모델과 뷰의 생명주기도 관리하고, 변경사항을 해당 요소에 알려줌
mvp 패턴은 mvc 패턴에서 컨트롤러가 프레젠터로 바뀐 패턴임.
프레젠터는 모델과 뷰를 이어주는 역할을 하고, 뷰와 프레젠터는 일대일 관계이기 때문에 MVC패턴보다 더 강한 결합을 가짐.
MVVM 패턴은 MVC의 C에 해당하는 컨트롤러가 View Model로 바뀐 패턴임
View Model은 View를 위한 모델이자 View를 나타내기 위한 데이터 처리를 하는 부분
MVC 패턴과는 다르게 커맨드와 데이터 바인딩을 가짐. 뷰와 뷰 모델 사이의 양방향 데이터 바인딩을 지원하며 UI를 별도의 코드 수정 없이 재사용할 수 있고 단위 테스트 하기 쉬움