디자인 패턴
Head First Design Patterns
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package org.example; class Duck { } class MallardDuck extends Duck { } class RedheadDuck extends Duck { } public class Main { public static void main(String[] args) { } } | cs |
클래스가 많아지면 코드로 대화하기 힘듦
-> UML 사용
상속은 항상 밑에서 위로(부모가 위)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package org.example; class Duck { public void quack(){ } public void swim(){ } public void display(){ } } class MallardDuck extends Duck { } class RedheadDuck extends Duck { } public class Main { public static void main(String[] args) { } } | cs |
자식에서 Ctrl+O 누르면 상속가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package org.example; class Duck { public void quack(){ } public void swim(){ } public void display(){ } } class MallardDuck extends Duck { @Override public void display() { System.out.println("MallardDuck"); } } class RedheadDuck extends Duck { @Override public void display() { System.out.println("RedheadDuck"); } } public class Main { public static void main(String[] args) { MallardDuck duck1 = new MallardDuck(); RedheadDuck duck2 = new RedheadDuck(); duck1.display(); duck2.display(); } } | cs |
관계를 어떻게 정할까 -> 프로그래밍에서의 디자인
날게 해달라는 주문이 들어옴
부모에 fly() 추가?
자식은 다 상속받을텐데 날지 않는 오리는?
reuse, maintenance
재사용, 유지보수
유지보수
=전체적인 아키텍처를 바꾸지않고 간다
주문이 고무오리였던 것
44쪽
인터페이스로 뺌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | package org.example; interface Flyable { void fly(); } interface Quackable { void quack(); } class Duck { public void swim(){ } public void display(){ } } class MallardDuck extends Duck implements Flyable, Quackable{ @Override public void display() { System.out.println("MallardDuck"); } @Override public void fly() { } @Override public void quack() { } } class RedheadDuck extends Duck implements Flyable, Quackable{ @Override public void display() { System.out.println("RedheadDuck"); } @Override public void fly() { } @Override public void quack() { } } class RubberDuck extends Duck implements Quackable{ @Override public void display() { super.display(); } @Override public void quack() { } } class DecoyDuck extends Duck { @Override public void display() { super.display(); } } public class Main { public static void main(String[] args) { MallardDuck duck1 = new MallardDuck(); RedheadDuck duck2 = new RedheadDuck(); duck1.display(); duck2.display(); } } | cs |
시스템이나 임베디드에서는 객체지향보단 알고리즘, 함수만 구현하면 됨
이렇게 디자인한 것이 잘한 짓일까?
-> 자유도가 높음
가이드가 없음
학교에서는 잘한 가이드
산업계에서는 잘한 가이드가 아님
나는지 안 나는지, 어떻게 나는지 등 옵션을 인터페이스에 줘야함
우는지 안 우는지, 높게 우는지, 낮게 우는지 등
인터페이스도 상속이 됨
51쪽
60쪽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | package org.example; interface FlyBehavior { public void fly(); } class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("날아다닌다"); } } class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("날지 못한다."); } } interface QuackBehavior { void quack(); } class Quack implements QuackBehavior { @Override public void quack() { } } class Squeak implements QuackBehavior { @Override public void quack() { } } class MuteQuack implements QuackBehavior { @Override public void quack() { } } interface Flyable { void fly(); } interface Quackable { void quack(); } class Duck { public void swim(){ } public void display(){ } } class MallardDuck extends Duck implements Flyable, Quackable{ @Override public void display() { System.out.println("MallardDuck"); } @Override public void fly() { } @Override public void quack() { } } class RedheadDuck extends Duck implements Flyable, Quackable{ @Override public void display() { System.out.println("RedheadDuck"); } @Override public void fly() { } @Override public void quack() { } } class RubberDuck extends Duck implements Quackable{ @Override public void display() { super.display(); } @Override public void quack() { } } class DecoyDuck extends Duck { @Override public void display() { super.display(); } } public class Main { public static void main(String[] args) { MallardDuck duck1 = new MallardDuck(); RedheadDuck duck2 = new RedheadDuck(); duck1.display(); duck2.display(); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | package org.example; interface FlyBehavior { public void fly(); } class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("날아다닌다"); } } class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("날지 못한다."); } } interface QuackBehavior { void quack(); } class Quack implements QuackBehavior { @Override public void quack() { } } class Squeak implements QuackBehavior { @Override public void quack() { } } class MuteQuack implements QuackBehavior { @Override public void quack() { } } interface Flyable { void fly(); } interface Quackable { void quack(); } class Duck { // has-a 관계(포함) is-a(상속 extends) // has-a FlyBehavior flyBehavior; QuackBehavior quackBehavior; public void swim(){ } public void display(){ } } class MallardDuck extends Duck{ MallardDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } @Override public void display() { System.out.println("MallardDuck"); } } class RedheadDuck extends Duck implements Flyable, Quackable{ @Override public void display() { System.out.println("RedheadDuck"); } @Override public void fly() { } @Override public void quack() { } } class RubberDuck extends Duck implements Quackable{ RubberDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); } @Override public void display() { super.display(); } @Override public void quack() { } } class DecoyDuck extends Duck { @Override public void display() { super.display(); } } public class Main { public static void main(String[] args) { MallardDuck duck1 = new MallardDuck(); RedheadDuck duck2 = new RedheadDuck(); RubberDuck duck3 = new RubberDuck(); duck1.display(); duck2.display(); duck1.flyBehavior.fly(); duck3.flyBehavior.fly(); duck3.quackBehavior.quack(); } } | cs |
60쪽 오리 상속 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | package org.example; interface FlyBehavior { void fly(); } class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("can fly"); } } class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("can't fly"); } } interface QuackBehavior { void quack(); } class Quack implements QuackBehavior { @Override public void quack() { System.out.println("Quack"); } } class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("Squeak"); } } class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("(Quite)"); } } class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public void swim() { } public void display() { } } class MallardDuck extends Duck implements FlyBehavior,QuackBehavior{ MallardDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } @Override public void display() { super.display(); } @Override public void fly() { flyBehavior.fly(); } @Override public void quack() { quackBehavior.quack(); } } class RedheadDuck extends Duck implements FlyBehavior, QuackBehavior{ RedheadDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } @Override public void display() { super.display(); } @Override public void fly() { flyBehavior.fly(); } @Override public void quack() { quackBehavior.quack(); } } class RubberDuck extends Duck implements FlyBehavior, QuackBehavior{ RubberDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new Squeak(); } @Override public void display() { super.display(); } @Override public void fly() { flyBehavior.fly(); } @Override public void quack() { quackBehavior.quack(); } } class DecoyDuck extends Duck implements FlyBehavior, QuackBehavior{ DecoyDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); } @Override public void display() { super.display(); } @Override public void fly() { flyBehavior.fly(); } @Override public void quack() { quackBehavior.quack(); } } public class Main { public static void main(String[] args) { MallardDuck ma = new MallardDuck(); RedheadDuck red = new RedheadDuck(); RubberDuck rub = new RubberDuck(); DecoyDuck de = new DecoyDuck(); ma.flyBehavior.fly(); red.flyBehavior.fly(); rub.flyBehavior.fly(); de.flyBehavior.fly(); ma.fly(); red.fly(); rub.fly(); de.fly(); ma.quackBehavior.quack(); red.quackBehavior.quack(); rub.quackBehavior.quack(); de.quackBehavior.quack(); ma.quack(); red.quack(); rub.quack(); de.quack(); } } | cs |
Strategy Pattern을 이용하여 영웅들의 공격(Attack) 기능을 구현하세요.
디자인패턴 중 스트래티지 패턴을 활용하여 롤플레잉 게임의 기능을 만들어 봅시다.
최종 부모클래스는 Hero 입니다.
영웅의 직업은 마법사(Wizard), 전사(Warrior), 기사(Knight), 소서리스(Sorceress) 입니다.
공격(Attack) 기능을 구현하고 싶은데 직업마다 공격법이 달랐으면 합니다.
마법사 - fireMagicAttack
전사 - punchAttack
기사 - swordAttack
소서리스 - iceMagicAttack
영웅들은 객체마을에서 단순히 attack()을 하면 각자 직업에 맞는 공격을 구현하고 싶습니다.
만들어 주세요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | package org.example; interface AttackBehavior { void Attack(); } class FireMagicAttack implements AttackBehavior { @Override public void Attack() { System.out.println("FireMagic"); } } class PunchAttack implements AttackBehavior { @Override public void Attack() { System.out.println("Punch"); } } class SwordAttack implements AttackBehavior { @Override public void Attack() { System.out.println("Sword"); } } class IceMagicAttack implements AttackBehavior { @Override public void Attack() { System.out.println("IceMagic"); } } class Hero { AttackBehavior attackBehavior; } class Wizard extends Hero implements AttackBehavior{ Wizard() { attackBehavior = new FireMagicAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } class Warrior extends Hero implements AttackBehavior{ Warrior() { attackBehavior = new PunchAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } class Knight extends Hero implements AttackBehavior{ Knight() { attackBehavior = new SwordAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } class Sorceress extends Hero implements AttackBehavior{ Sorceress() { attackBehavior = new IceMagicAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } public class Main { public static void main(String[] args) { Wizard wizard = new Wizard(); Warrior warrior = new Warrior(); Knight knight = new Knight(); Sorceress sorceress = new Sorceress(); wizard.Attack(); warrior.Attack(); knight.Attack(); sorceress.Attack(); } } | cs |
친구 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | interface AttackBehavior{ void attack(int damage,Hero hero); } class fireMagicAttack implements AttackBehavior{ @Override public void attack(int damage,Hero hero) { System.out.println("불 마법! "+damage+"의 damage를 입힘"); hero.HP-=damage; System.out.println("대상의 남은체력: "+hero.HP); } } class punchAttack implements AttackBehavior{ @Override public void attack(int damage,Hero hero) { System.out.println("주먹 공격!"+damage+"의 damage를 입힘"); hero.HP-=damage; System.out.println("대상의 남은체력: "+hero.HP); } } class swordAttack implements AttackBehavior{ @Override public void attack(int damage,Hero hero) { System.out.println("검 공격!"+damage+"의 damage를 입힘"); hero.HP-=damage; System.out.println("대상의 남은체력: "+hero.HP); } } class iceMagicAttack implements AttackBehavior{ @Override public void attack(int damage,Hero hero) { System.out.println("얼음 마법!"+damage+"의 damage를 입힘"); hero.HP-=damage; System.out.println("대상의 남은체력: "+hero.HP); } } class Hero{ int HP; int Damage; AttackBehavior attackBehavior; } class Wizard extends Hero{ Wizard(){ HP=100; Damage=10; attackBehavior=new fireMagicAttack(); } public void attack(Hero hero){ attackBehavior.attack(this.Damage,hero); } } class Warrior extends Hero{ Warrior(){ HP=200; Damage=4; attackBehavior=new punchAttack(); } public void attack(Hero hero){ attackBehavior.attack(this.Damage,hero); } } class Knight extends Hero{ Knight(){ HP=150; Damage=6; attackBehavior=new swordAttack(); } public void attack(Hero hero){ attackBehavior.attack(this.Damage,hero); } } class Sorceress extends Hero{ Sorceress(){ HP=100; Damage=10; attackBehavior=new iceMagicAttack(); } public void attack(Hero hero){ attackBehavior.attack(this.Damage,hero); } } public class Main { public static void main(String[] args) { Wizard wizard=new Wizard(); Warrior warrior=new Warrior(); Knight knight=new Knight(); Sorceress sorceress=new Sorceress(); wizard.attack(warrior); warrior.attack(knight); knight.attack(sorceress); sorceress.attack(wizard); } } | cs |
59쪽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | package org.example; interface AttackBehavior { void Attack(); } class FireMagicAttack implements AttackBehavior { @Override public void Attack() { System.out.println("FireMagic"); } } class PunchAttack implements AttackBehavior { @Override public void Attack() { System.out.println("Punch"); } } class SwordAttack implements AttackBehavior { @Override public void Attack() { System.out.println("Sword"); } } class IceMagicAttack implements AttackBehavior { @Override public void Attack() { System.out.println("IceMagic"); } } class Hero { AttackBehavior attackBehavior; // delegate public void performAttack() { attackBehavior.Attack(); } } class Wizard extends Hero implements AttackBehavior{ Wizard() { attackBehavior = new FireMagicAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } class Warrior extends Hero implements AttackBehavior{ Warrior() { attackBehavior = new PunchAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } class Knight extends Hero implements AttackBehavior{ Knight() { attackBehavior = new SwordAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } class Sorceress extends Hero implements AttackBehavior{ Sorceress() { attackBehavior = new IceMagicAttack(); } @Override public void Attack() { attackBehavior.Attack(); } } public class Main { public static void main(String[] args) { Wizard wizard = new Wizard(); Warrior warrior = new Warrior(); Knight knight = new Knight(); Sorceress sorceress = new Sorceress(); wizard.Attack(); warrior.Attack(); knight.Attack(); sorceress.Attack(); wizard.performAttack(); } } | cs |
세 가지 방법이 있다.
wizard.attackBehavior.Attack();
wizard.Attack();
wizard.performAttack();
마지막 방법은 delegate를 이용
Observer pattern
옵저버 패턴
90쪽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | package org.example; import java.util.ArrayList; import java.util.List; interface Observer { void update(int value); } interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); 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 each문 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); } } | cs |
94쪽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | 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); } } | cs |
값이 바뀌면 display()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | package org.example; import java.util.ArrayList; import java.util.List; interface Observer { void update(int value); } interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); 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 each문 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; display(); } 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); } } | cs |
strategy, observer
두 패턴은 중요하면서도 간단함
객체지향을 잘 사용하기 위해서 스프링이 존재
백엔드는 패턴을 잘 하는 사람이 잘할 확률이 높다
Observer는 안드로이드에서 잘 쓰임 -> Push
옵저버(Observer) 패턴을 이용하여 코로나 확진자 상황을 알려주세요.
여러분이 코로나 상황실에 개발 보조로 갑자기 취업이 되었습니다.
개발 보조이기 때문에 큰 일은 시키지 않고 경북의 3개의 지자체 안동, 구미, 김천 지역의 코로나 확진자
상황을 보고하는 업무를 맡게 되었습니다.
현재는 확진자 정보가 수정이 되면 그 때마다 직접 세곳의 정보를 전산망에 기입하여 알려주고 있습니다.
한 3일은 입력해 주었는데 데이터가 수정될 때 마다 알려 주자니 불편하고 힘들어지기 시작했습니다.
그래서 프로그램을 만들어서 해결하려고 합니다.
------------------------------------------
안동 : 1명 전국: 1200명
김천 : 3명 전국: 1200명
구미 : 7명 전국: 1200명
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | 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); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | package org.example; import java.util.ArrayList; import java.util.List; interface Observer{ void update(int count, String name); } class MyObserver implements Observer{ private int total; private int count; private String name; private List<Subject> subjects; MyObserver(AndongSubject andongSubject, GimCheonSubject gimCheonSubject, GumiSubject gumiSubject){ total = 1200; subjects = new ArrayList<Subject>(); subjects.add(andongSubject); subjects.add(gimCheonSubject); subjects.add(gumiSubject); subjects.get(0).registerObserver(this); subjects.get(1).registerObserver(this); subjects.get(2).registerObserver(this); } @Override public void update(int count, String name) { this.count = count; this.name = name; total += count; display(this.count, this.name, total); } static void display(int count, String name, int total) { System.out.println(name+"의 확진자는 "+count+"명 입니다. 총 : "+total); } } interface Subject{ void registerObserver(Observer o); void removeObserver(Observer o); void notisfy(int count, String name); } class AndongSubject implements Subject{ List<Observer> observers; int count; String name; AndongSubject(){ 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 notisfy(int count, String name) { for(Observer observer : observers){ observer.update(count,name); } } public void setup(int count, String name){ this.count = count; this.name = name; notisfy(this.count, this.name); } } class GimCheonSubject implements Subject{ List<Observer> observers; int count; String name; GimCheonSubject(){ 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 notisfy(int count, String name) { for(Observer observer : observers){ observer.update(count,name); } } public void setup(int count, String name){ this.count = count; this.name = name; notisfy(this.count, this.name); } } class GumiSubject implements Subject{ List<Observer> observers; int count; String name; GumiSubject(){ 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 notisfy(int count, String name) { for(Observer observer : observers){ observer.update(count,name); } } public void setup(int count, String name){ this.count = count; this.name = name; notisfy(this.count, this.name); } } public class Main { public static void main(String[] args) { AndongSubject andongSubject = new AndongSubject(); GimCheonSubject gimCheonSubject = new GimCheonSubject(); GumiSubject gumiSubject = new GumiSubject(); MyObserver myObserver = new MyObserver(andongSubject,gimCheonSubject, gumiSubject); andongSubject.setup(1,"안동"); gimCheonSubject.setup(3, "김천"); gumiSubject.setup(7,"구미"); } } | cs |
자료구조, 알고리즘은 나무
디자인패턴은 숲
Decorator Pattern
119쪽 -> 지저분해짐
-> 결국 폐기로 생명력이 마무리됨
결론
129쪽
Decorator를 만들어라
먼저 결과 볼 소스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | package pattern.decorator.starbucks; //음료의 추상 클래스 abstract class Beverage { String description = "알 수 없는 음료"; public String getDescription() { return description; } public abstract double cost(); } //음료-에소프레소 class Espresso extends Beverage { public Espresso() { description = "Espresso"; } public double cost() { return 1.99; } } //음료-Decaf class Decaf extends Beverage { public Decaf() { description = "Decaf Coffee"; } public double cost() { return 1.05; } } //음료-하우스블렌드 class HouseBlend extends Beverage { public HouseBlend() { description = "House Blend Coffee"; } public double cost() { return .89; } } //음료-다크로스트 class DarkRoast extends Beverage { public DarkRoast() { description = "Dark Roast Coffee"; } public double cost() { return .99; } } //추상클래스 - 추가 데코레이션 abstract class CondimentDecorator extends Beverage { Beverage beverage; public abstract String getDescription(); } //데코레이션 - 우유 class Milk extends CondimentDecorator { public Milk(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Milk"; } public double cost() { return .10 + beverage.cost(); } } //데코레이션 - 모카 class Mocha extends CondimentDecorator { public Mocha(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Mocha"; } public double cost() { return .20 + beverage.cost(); } } //데코레이션 - 두유 class Soy extends CondimentDecorator { public Soy(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Soy"; } public double cost() { return .15 + beverage.cost(); } } //데코레이션-휘핑 class Whip extends CondimentDecorator { public Whip(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Whip"; } public double cost() { return .10 + beverage.cost(); } } public class Main { public static void main(String[] args) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); System.out.println(beverage2.getDescription() + " $" + beverage2.cost()); Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); System.out.println(beverage3.getDescription() + " $" + beverage3.cost()); } } | cs |
'Java' 카테고리의 다른 글
| 스마트팩토리 12주 57일차 java 9일차 (0) | 2021.07.16 |
|---|---|
| 스마트팩토리 12주 56일차 java 8일차 (0) | 2021.07.15 |
| 스마트팩토리 11주 54일차 java 6일차 (0) | 2021.07.14 |
| 스마트팩토리 11주 53일차 java 5일차 (0) | 2021.07.12 |
| 스마트팩토리 11주 52일차 java 4일차 (0) | 2021.07.08 |




최근댓글