[Java]_JAVA로 디자인패턴 공부_Observer Pattern
Observer Pattern:
객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다.
ConcreteSubject => SimpleSubject
ConcreteObserver=> SimpleObserver
로 변경해서 코딩했습니다.
package org.example;
import java.util.ArrayList;
import java.util.List;
interface Observer {
public void update(int value);
}
interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
}
class SimpleSubject implements Subject {
private List<Observer> observers;
private int value = 0;
//생성자
public SimpleSubject() {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObserver() {
for(Observer observer : observers){
observer.update(value);
}
}
public void setValue(int value){
this.value = value;
notifyObserver();
}
}
class SimpleObserver implements Observer {
private int value;
private Subject simpleSubject;
//생성자
public SimpleObserver(Subject simpleSubject) {
this.simpleSubject = simpleSubject;
simpleSubject.registerObserver(this);
}
@Override
public void update(int value) {
this.value = value;
}
public void display() {
System.out.println("Value : " + value);
}
}
public class Main {
public static void main(String[] args) {
SimpleSubject simpleSubject = new SimpleSubject();
SimpleObserver simpleObserver = new SimpleObserver(simpleSubject);
simpleSubject.setValue(80);
simpleObserver.display();
simpleSubject.removeObserver(simpleObserver);
}
}
package pattern.observer.weather;
import java.util.ArrayList;
import java.util.List;
interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
interface Observer {
public void update(float temp, float humidity, float pressure);
}
interface DisplayElement {
public void display();
}
class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<Observer>();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
observers.remove(o);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private WeatherData weatherData;
public CurrentConditionsDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("Current conditions: " + temperature
+ "F degrees and " + humidity + "% humidity");
}
}
class StatisticsDisplay implements Observer, DisplayElement {
private float maxTemp = 0.0f;
private float minTemp = 200;
private float tempSum= 0.0f;
private int numReadings;
private WeatherData weatherData;
public StatisticsDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temp, float humidity, float pressure) {
tempSum += temp;
numReadings++;
if (temp > maxTemp) {
maxTemp = temp;
}
if (temp < minTemp) {
minTemp = temp;
}
display();
}
public void display() {
System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)
+ "/" + maxTemp + "/" + minTemp);
}
}
class ForecastDisplay implements Observer, DisplayElement {
private float currentPressure = 29.92f;
private float lastPressure;
private WeatherData weatherData;
public ForecastDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temp, float humidity, float pressure) {
lastPressure = currentPressure;
currentPressure = pressure;
display();
}
public void display() {
System.out.print("Forecast: ");
if (currentPressure > lastPressure) {
System.out.println("Improving weather on the way!");
} else if (currentPressure == lastPressure) {
System.out.println("More of the same");
} else if (currentPressure < lastPressure) {
System.out.println("Watch out for cooler, rainy weather");
}
}
}
class HeatIndexDisplay implements Observer, DisplayElement {
float heatIndex = 0.0f;
private WeatherData weatherData;
public HeatIndexDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float t, float rh, float pressure) {
heatIndex = computeHeatIndex(t, rh);
display();
}
private float computeHeatIndex(float t, float rh) {
float index = (float)((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh)
+ (0.00941695 * (t * t)) + (0.00728898 * (rh * rh))
+ (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +
(0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 *
(rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) +
(0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +
0.000000000843296 * (t * t * rh * rh * rh)) -
(0.0000000000481975 * (t * t * t * rh * rh * rh)));
return index;
}
public void display() {
System.out.println("Heat index is " + heatIndex);
}
}
public class ObserverWeatherMain {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 90, 29.2f);
}
}
여러분이 코로나 상황실에 개발 보조로 갑자기 취업이 되었습니다.
개발 보조이기 때문에 큰 일은 시키지 않고 경북의 3개의 지자체 안동, 구미, 김천 지역의 코로나 확진자
상황을 보고하는 업무를 맡게 되었습니다.
현재는 확진자 정보가 수정이 되면 그 때마다 직접 세곳의 정보를 전산망에 기입하여 알려주고 있습니다.
한 3일은 입력해 주었는데 데이터가 수정될 때 마다 알려 주자니 불편하고 힘들어지기 시작했습니다.
그래서 프로그램을 만들어서 해결하려고 합니다.
------------------------------------------
안동 : 1명 전국: 1200명
김천 : 3명 전국: 1203명
구미 : 7명 전국: 1210명
import java.util.ArrayList;
import java.util.List;
interface Observer{
public void update(String local,int patient);
}
interface BroadCastElement{
void broadCast(String local);
}
interface Subject{
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
class AndongCoronaData implements Subject {
private List<Observer> observers;
private int patient;
AndongCoronaData() {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update("안동",this.patient);
}
}
public void setPatient(int patient) {
this.patient = patient;
notifyObservers();
}
}
class GumiCoronaData implements Subject {
private List<Observer> observers;
private int patient;
GumiCoronaData() {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update("구미",this.patient);
}
}
public void setPatient(int patient) {
this.patient = patient;
notifyObservers();
}
}
class GimcheonCoronaData implements Subject {
private List<Observer> observers;
private int patient;
GimcheonCoronaData() {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update("김천",this.patient);
}
}
public void setPatient(int patient) {
this.patient = patient;
notifyObservers();
}
}
class DataCenter implements Observer,BroadCastElement{
int patient;
int nationWidePatient;
AndongCoronaData andongCoronaData;
GumiCoronaData gumiCoronaData;
GimcheonCoronaData gimcheonCoronaData;
DataCenter(int nationWidePatient){
this.nationWidePatient=nationWidePatient;
}
public void setAndongCoronaData(AndongCoronaData andongCoronaData) {
this.andongCoronaData = andongCoronaData;
andongCoronaData.registerObserver(this);
}
public void setGumiCoronaData(GumiCoronaData gumiCoronaData) {
this.gumiCoronaData = gumiCoronaData;
gumiCoronaData.registerObserver(this);
}
public void setGimcheonCoronaData(GimcheonCoronaData gimcheonCoronaData) {
this.gimcheonCoronaData = gimcheonCoronaData;
gimcheonCoronaData.registerObserver(this);
}
@Override
public void broadCast(String local) {
System.out.println(local+" : "+patient+"명 전국 : "+nationWidePatient+"명");
}
@Override
public void update(String local,int patient) {
this.nationWidePatient-=this.patient;
this.patient=patient;
this.nationWidePatient+=this.patient;
broadCast(local);
}
}
public class Main {
public static void main(String[] args) {
AndongCoronaData andongCoronaData=new AndongCoronaData();
GumiCoronaData gumiCoronaData=new GumiCoronaData();
GimcheonCoronaData gimcheonCoronaData=new GimcheonCoronaData();
DataCenter dataCenter=new DataCenter(1200);
dataCenter.setAndongCoronaData(andongCoronaData);
dataCenter.setGumiCoronaData(gumiCoronaData);
dataCenter.setGimcheonCoronaData(gimcheonCoronaData);
andongCoronaData.setPatient(1);
gimcheonCoronaData.setPatient(3);
gumiCoronaData.setPatient(7);
}
}
Strategy 패턴보다 이해하면서 사용하기 힘들었고 문제를 풀지 못해 풀이를 참고했다. 좀 더 시간을 들여서 공부해야 할것 같다.