SMALL

Observer Pattern

옵저버 패턴이란

객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여
상태 변화가 있을 때마다 옵저버들에게 통지하도록 하는 디자인 패턴입니다.

 > 어떤 객체의 변경 사항이 발생하였을 때 이와 연관된 객체들에게 알려주는 디자인 패턴이다.

 

 

 

옵저버 패턴에는 주체 객체와 상태의 변경을 알아야 하는 관찰 객체(Observer Object)가 존재하며 

이들의 관계는 보통 1:N이다. ( 1:1도 가능 ) 

 

Observer Pattern 특징

  • Loose Coupling : 상호작용을 하긴 하지만, 서로에 대해 잘 모른다
                                객체 간의 의존성을 제거할 수 있다

 

객체 간의 의존성을 줄이기 위해서 interface를 정의한다 ( Subject, Observer ) 

public interface Subject {

	public void registerObserver(Observer o);

	public void removeObserver(Observer o);

	public void notifyObserver();
}

public interface Observer {

	public void update(float tmp, float humidity, float pressure);
	
}

public interface DisplayElement {
	public void display();
}

 

Subject의 구현체, Observer List를 가지고 있다

public class WeatherData implements Subject {

	private List<Observer> observers;
	private float temperature;
	private float humidity;
	private float pressure;

	public WeatherData() {
		observers = new ArrayList<Observer>();
	}

	@Override
	public void registerObserver(Observer o) {
		observers.add(o);
	}

	@Override
	public void removeObserver(Observer o) {
		int idx = observers.indexOf(o);

		if (idx >= 0) {
			observers.remove(idx);
		}
	}

	@Override
	public void notifyObserver() {
		for (Observer observer : observers) {
			observer.update(temperature, humidity, pressure);
		}
	}
	
	public void measurementsChanged() {
		notifyObserver();
	}
	
	public void setMeasurements(float temperature, float humidity, float pressure) {
		this.temperature = temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		
		measurementsChanged();
	}

}

 

Observer의 구현체, subject를 가지고 있고, 그를 통해 자신을 등록한다 

public class CurrentConditionsDisplay implements Observer, DisplayElement {

	private float temperature;
	private float humidity;
	private WeatherData weatherData;

	public CurrentConditionsDisplay(WeatherData weatherData) {
		this.weatherData = weatherData;
		this.weatherData.registerObserver(this);
	}

	@Override
	public void display() {
		System.out.println("Current Condition : " + temperature + " F degrees , " 
        						+ humidity + " % humidity");

	}

	@Override
	public void update(float tmp, float humidity, float pressure) {
		this.temperature = tmp;
		this.humidity = humidity;

		display();
	}

}

 

수행 코드 

	public static void main(String[] args) {
		WeatherData weatherData = new WeatherData();
		
		CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
		
		weatherData.setMeasurements(80, 65, 30.4f);
		weatherData.setMeasurements(82, 70, 29.2f);
		weatherData.setMeasurements(78, 90, 28.4f);
	}

 

Java 개발자라면, java.util에서 제공하는 Observer 패턴 관련 코드를 이용할 수 있다.

다만, Subject에 해당하는 Observable은 인터페이스가 아니고 상속받아야 해서 사용하는데 제한이 있을 수 있다.

import java.util.Observable;
import java.util.Observer;

 

 

 

 

LIST
SMALL

Strategy Pattern

객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고, 유사한 행위들을 캡슐화하는 인터페이스를 정의하여, 객체의 행위를 동적으로 바꾸고 싶은 경우 직접 행위를 수정하지 않고 전략을 바꿔주기만 함으로써 행위를 유연하게 확장하는 방법을 말합니다.

 

간단히 말해서 

객체가 할 수 있는 행위들 각각을 전략으로 만들어 놓고, 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것만으로 행위의 수정이 가능하도록 만든 패턴입니다.

 

 

객체지향 원칙

  • 바뀌는 부분은 캡슐화한다
  • 상속보다는 구성을 활용한다
  • 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다

전략 패턴에서는 위의 원칙들을 포함하는 구조가 가능하다.

 

public abstract class Duck {
	
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	
	public Duck() {
		
	}
	
	public void performFly() {
		flyBehavior.fly();
	}
	
	public void performQuack() {
		quackBehavior.quack();
	}
	
	public abstract void display();
	
	public void swim() {
		System.out.println("s w i m ~ ~ ");
	}
	
	public void setFlyBehavior(FlyBehavior fb) {
		flyBehavior = fb;
	}
	
	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}
	
}

Duck에서는 FlyBehavior, QuackBehavior에 해당하는 전략을 가지고 있다.

 

public interface FlyBehavior {
	public void fly();
}

public interface QuackBehavior {
	public void quack();
}

 

그리고 마지막으로, Duck과 전략들의 구현체들을 보자

public class FlyNoWay implements FlyBehavior {
	@Override
	public void fly() {
		System.out.println(" I cannot fly ~ ");
	}
}

public class FlyWithWings implements FlyBehavior {
	@Override
	public void fly() {
		System.out.println(" fly in the moon ~ ");
	}
}

public class Quack implements QuackBehavior {
	@Override
	public void quack() {
		System.out.println("Quack ~~ Quack ~");
	}
}

public class Squeak implements QuackBehavior{
	@Override
	public void quack() {
		System.out.println("Squeak ~~ squeak ~ ");
	}
}

 

public class MallardDuck extends Duck {

	public MallardDuck() {
		quackBehavior = new Quack();
		flyBehavior = new FlyWithWings();
	}
	
	@Override
	public void display() {
		System.out.println("I'm MallarDuck~~ ~");
	}

}
LIST

+ Recent posts