Java

[Java]_JAVA로 디자인패턴 공부_Observer Pattern

롶롶예 2021. 7. 14. 16:46

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 패턴보다 이해하면서 사용하기 힘들었고 문제를 풀지 못해 풀이를 참고했다. 좀 더 시간을 들여서 공부해야 할것 같다.