02. 디자인 패턴 구조

옵저버 패턴

  • 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체에게 연락이 가고 자동으로 내용이 갱신되는 방식
  • one to many 의존성 정의
  • 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체에게 연락이 가고 자동으로 내용이 갱신되는 방식으로 (one-to-many) 의존성을 정의함.
  • 옵저버 패턴은 객체들 사이에 일대다 관계를 정의함.
  • Subject는 동일한 인터페이스를 써서 옵저버에게 연락함.
  • Observer 인터페이스를 구현하기만 하면 어떤 구상 클래스의 옵저버라도 패턴에 참여할 수 있음.
  • Subject는 옵저버들이 Observer인터페이스를 구현한다는 것을 제외하면 옵저버에 관해 전혀 모름. (느슨한 결합)
  • 옵저버 패턴을 사용함녀 주제가 데이터를 보내거나 (push) 옵저버가 데이터를 가져올 (pull) 수 있음. -> pull 방법이 더 옳은 방식.
  • swing , RxJava, 자바빈, RMI,코코아, 스위프트, 자바스크립트 => 옵저버 패턴 사용 예
  • 출판-구독 패턴(:여러개의 주제와 메시지 유형이 있는 복잡한 상황에서 사용)과 유사.
  • 관련 주제 : MVC (모델-뷰-컨트롤러)
  1. 옵저버 패턴에서 변하는 것은 주제의 상태와 옵저버의 갯수, 형식
  2. 옵저버 패턴에서는 주제를 바꾸지 않고도 주제의 상태에 의존하는 객체들을 바꿀 수 있습니다.
  3. 주제와 옵저버에서 모두 인터페이스를 사용했습니다. 주제는 Subject 인터페이스로, Observer인터페이스를 구현하는 객체들의 등록과 탈퇴를 관리하고, 그런 객체들에게 연락을 돌립니다. (느슨한 결합)
  4. 옵저버 패턴에서는 구성을 활용해서 옵저버들을 관리합니다. 주제와 옵저버 사이의 관계는 상속이 아니라 구성으로 이루어짐.

느슨한 결합 (Loose Coupling)

  • 객체들이 상호작용 할 수는 있지만, 서로를 잘 모르는 관계를 의미.
  • 상호작용하는 객체 사이에는 가능하면 느슨한 결합을 사용하는 것이 좋음
  • 느슨하게 결합하는 디자인을 사용하면 변경 사항이 생겨도 무난히 처리할 수 있는 유연한 객체지향 시스템을 구축할 수 있음. (객체 사이의 상호의존성을 최소화.)

데코레이션 패턴

  • 객체에 추가요소를 동적으로 더하는 방식
  • 서브클래스를 만들때보다 유연하게 기능 확장가능.
  • OCP :
  • 상속대신 데코레이터 패턴으로 행동을 확장할 수 있습니다.
  • 기존 코드 수정 없이 행동을 확장해야 하는 상황이 있습니다.
  • 구성과 위임으로 실행중에 새로운 행동을 추가할 수 있습니다.
  • 데코레이터 패턴은 구상 구성요소를 감싸주는 데코레이터를 사용합니다.
  • 데코레이터 클래스 형식은 그 클래스가 감싸는 클래스 형식을 반영합니다 (상속이나 인터페이스 구현으로 자신이 감쌀 클래스와 같은 형식을 가집니다.)
  • 데코레이터는 자기가 감싸고 있는 구성요소의 메소드를 호출한 결과에 새로운 기능을 더함으로써 행동을 확장합니다.
  • 구성요소의 클라이언트는 데코레이터의 존재를 알 수 없습니다. (클라이언트가 구성요소의 구체적인 형식에 의존하는 경우는 예외입니다.)
  • 데코레이터 패턴을 사용하면 자잘한 객체가 매우 많이 추가될 수가 있고, 코드가 필요 이상으로 복잡해집니다.

팩토리 메서드 패턴

  • 팩토리 메서드 패턴에서는 객체를 생성할 때 필요한 인터페이스(유연성 확장성)를 만듭니다. 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정합니다. 팩토리 메서드 패턴을 이용하면 클래스 인스턴스 만드는 일을 서브클래스에게 맡기게 됩니다 (바뀌는 부분을 캡슐화 하기 )
  • 구상형식의 인스턴스를 만드는 작업을 캡슐화 (서브클래서에서 객체를 만들기)
    • Creator 추상클래스에서 객체를 만드는 메서드(팩토리 메서드용 인터페이스) 제공
    • Creator 추상클래스에 구현되어 있는 다른 메서드는 팩토리 메서드에 의해 생산된 제품으로 필요한 작업 처리.
    • 실제 팩토리 메서드를 구현하고 제품 (객체 인스턴스)을 만드는 일은 서브클래스에서 함.
    • "팩토리 메서드 패턴에서는 어떤 클래스의 인스턴스를 만들지를 서브클래스에서 결정한다." => 사용하는 서브클래스에 따라 생산되는 객체 인스턴스가 결정.
  • 제품을 생산하는 부분과 사용하는 부분을 분리 (느슨한 결합)

추상 팩토리 패턴

추상 팩토리 패턴은 구상 클래스에 의존하지 않고도 서로 연관되거나 의존적인 객체로 이루어진 제품군을 생산하는 인터페이스를 제공. 구상클래스는 서브 클래스에서 만듬.

싱글턴 패턴

  • 클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공함.
  • 생성자를 private으로 저장 => 단 한개만 만들기
  • 필요할 때 인스턴스를 달라고 요청 : getInstance() 정적메서드
  • ex. 연결 풀이나 스레드 풀가 같은 자원 풀 관리에 사용
  • enum을 대체하면 간단하게 싱글턴 패턴을 구현할 수 있다.
package headfirst.designpatterns.singleton.enumS;
 
public enum Singleton {
	UNIQUE_INSTANCE;
 
	// other useful fields here
 
	// other useful methods here
	public String getDescription() {
		return "I'm a thread safe Singleton!";
	}
}
package headfirst.designpatterns.singleton.enumS;
 
public class SingletonClient {
	public static void main(String[] args) {
		Singleton singleton = Singleton.UNIQUE_INSTANCE;
		System.out.println(singleton.getDescription());
	}
}