ν κ°μ²΄μ μνκ° λ°λλ©΄ κ·Έ κ°μ²΄μ μμ‘΄νλ λ€λ₯Έ κ°μ²΄μκ² μ°λ½μ΄ κ°κ³ μλμΌλ‘ λ΄μ©μ΄ κ°±μ λλ λ°©μμΌλ‘ μΌλλ€(one-to-many) μμ‘΄μ±μ μ μνλ€. (= μΌμ’ μ λΈλ‘λμΊμ€ν λ°©μ)
- μνλ₯Ό κ°μ§κ³ μλ κ°μ²΄λ₯Ό
Subject
, μ΄ μνλ₯Ό λͺ¨λν°λνλ κ°μ²΄λ₯ΌObserver
λΌκ³ νλ€. - κ°μ²΄μ μν λ³νμ κ΄μ¬ μλ Observerκ° λͺ κ°μΈμ§μ μκ΄ μμ΄ μλ¦Όμ΄ κ°λλ‘ κ΅¬νν΄μΌ νλ€.
- Subject, Observerλ₯Ό λΆλ¦¬ ꡬννκΈ° λλ¬Έμ, Subjectμ Observerκ° κ°κ° λ³κ²½μ¬νμ΄ μ겨λ μλ‘μκ² μν₯μ λ―ΈμΉμ§ μλλ€. (= λμ¨ν κ²°ν©)
- Observerλ₯Ό μΈμ λ μ§ μλ‘ μΆκ°νκ±°λ μ κ±°ν μ μλ€.
- μλ‘μ΄ νμμ Observerλ₯Ό μΆκ°ν μ μλ€.
- μ΅μ μνκ°μ κ°μ Έμ€λ λ°©λ²μ 2κ°μ§μ΄λ€.
- λ°©λ² 1: Subjectκ° μ 체 Observerμκ² Pushνλ λ°©λ² (= Subjectκ° μνλ₯Ό μΈμλ‘ λ겨 Observerμμ λ³κ²½)
- λ°©λ² 2: Observerκ° Subjectλ‘λΆν° μνλ₯Ό Pullνλ λ°©λ² (= update λ©μλ ꡬν μ getter ν¨μλ‘ Subjectμ μνλ₯Ό κ°μ Έμ λ³κ²½)
from abc import ABCMeta, abstractmethod
class Subject:
__metaclass__ = ABCMeta
@abstractmethod
def registerObserver(self, observer):
pass
@abstractmethod
def removeObserver(self, observer):
pass
@abstractmethod
def notifyObservers():
pass
class WeatherData(Subject):
def __init__(self):
self._observers = []
self._temperature = None
self._humidity = None
self._pressure = None
def registerObserver(self, observer):
self._observers.append(observer)
def removeObserver(self, obeserver):
try:
self._observers.remove(observer)
except:
pass
def notifyObservers(self):
for observer in self._observers:
observer.update(self._temperature, self._humidity, self._pressure)
def measurementChanged(self):
self.notifyObservers()
def setMeasurements(self, temperature, humidity, pressure):
self._temperature = temperature
self._humidity = humidity
self._pressure = pressure
self.measurementChanged()
class Observer:
__metaclass__ = ABCMeta
@abstractmethod
def update(self, temp, humidity, pressure):
pass
class DisplayElement:
__metaclass__ = ABCMeta
@abstractmethod
def display(self):
pass
class CurrentConditionsDisplay(Observer, DisplayElement):
def __init__(self, weather_data):
self._temperature = None
self._humidity = None
self._weather_data = weather_data
weather_data.registerObserver(self)
def update(self, temperature, humidity, pressure):
self._temperature = temperature
self._humidity = humidity
self.display()
def display(self):
print(f"νμ¬ μ‘°κ±΄: μ¨λ {self._temperature} Β°F / μ΅λ {self._humidity}");
ν΄λμ€λ νμ₯μλ μ΄λ € μμ΄μΌ νμ§λ§ λ³κ²½μλ λ«ν μμ΄μΌ νλ€.
https://blog.itcode.dev/posts/2021/08/14/open-closed-principle
κ°μ²΄μ μΆκ° μμλ₯Ό λμ μΌλ‘ λν μ μλ λ°©μμΌλ‘ μλΈν΄λμ€λ₯Ό λ§λ€ λλ³΄λ€ ν¨μ¬ μ μ°νκ² κΈ°λ₯μ νμ₯ν μ μλ€.
- λ°μ½λ μ΄ν° μνΌν΄λμ€λ μ₯μν κ°μ²΄μ μνΌν΄λμ€μ κ°λ€.
- ν κ°μ²΄μ μ¬λ¬ κ°μ λ°μ½λ μ΄ν°λ₯Ό κ°μ μ μλ€.
- λ°μ½λ μ΄ν°λ μ₯μν κ°μ²΄μκ² μ΄λ€ νλμ μμνλ μΌ λ§κ³ λ μΆκ° μμ μ μνν μ μλ€.
- λ°μ½λ μ΄ν°μμ "μμ"μ μ¬μ©νλ μ΄μ λ κ΅¬μ± μμμμ νμλ― λ§μΆκΈ° μν¨μ΄λ€.
- κ΅¬μ± μμκ° μΆμ ν΄λμ€λΌλ©΄ λκ°μ΄ μΆμ ν΄λμ€λ₯Ό, μΈν°νμ΄μ€λΌλ©΄ μΈν°νμ΄μ€λ‘ ꡬννλ€.
- μλ‘μ΄ κΈ°λ₯μ λνκ³ κ΅¬μ± μμλ λ°μ½λ μ΄ν°μ μ‘΄μ¬λ₯Ό μ μ μλ€λ μ μμ λ§€μ° νμ₯μ±μ΄ λμ§λ§, λ€μκ³Ό κ°μ λ¨μ μ΄ μλ€.
- μμν ν΄λμ€κ° λ§μ΄ μΆκ°λλ κ²½μ°λ₯Ό λ³Ό μ μλ€.
- κ΅¬μ± μμλ₯Ό μ΄κΈ°ννλ λ° νμν μ½λκ° ν¨μ¬ 볡μ‘ν΄μ§λ€.
from abc import ABCMeta, abstractmethod
class Beverage:
__metaclass__ = ABCMeta
def __init__(self):
self._description = "Unknown Beverage"
def get_description(self):
return self._description
@abstractmethod
def cost(self):
pass
class Espresso(Beverage):
def __init__(self):
self._description = "Espresso"
def cost(self):
return 1.99
class CondimentDecorator(Beverage):
__metaclass__ = ABCMeta
@abstractmethod
def get_description():
pass
class Mocha(CondimentDecorator):
def __init__(self, beverage):
self._beverage = beverage
def get_description(self):
return self._beverage.get_description() + ", Mocha"
def cost(self):
return .20 + self._beverage.cost()
if __name__ == "__main__":
beverage = Espresso()
print(beverage.get_description() + " $" + str(beverage.cost())) # Espresso $1.99
beverage2 = Espresso()
beverage2 = Mocha(beverage2)
beverage2 = Mocha(beverage2)
print(beverage2.get_description() + " $" + str(beverage2.cost())) # Espresso, Mocha, Mocha $2.39
- https://blog.itcode.dev/posts/2021/08/17/dependency-inversion-principle
- https://blog.hexabrain.net/395
- νν¬ λ©μλ: "μ¬μ©ν΄λ λκ³ μν΄λ λκ³ , μ¬μ©νλ€λ©΄ μμ ν΄λ λκ³ "
- νμλ‘ μ¬μ©ν΄μΌ νλ λ©μλλΌλ©΄ μΆμ λ©μλλ‘ μ μ, μ νμ μΌλ‘ μ¬μ©ν΄μΌ νλ λ©μλλΌλ©΄ νν¬ λ©μλλ‘ μ μ\
- Comparable(μκΈ° μμ κ³Ό 맀κ°λ³μ κ°μ²΄ λΉκ΅) vs Comparator(λ 맀κ°λ³μ λΉκ΅) (https://st-lab.tistory.com/243)
- ν¬νλ¦Ώ λ©μλ ν¨ν΄: "μ¬λ¬ λ©μλλ‘ κ΅¬μ±λ λ©μλμ΄κ³ κ·Έ λ©μλ μ€ μΆμλ©μλκ° μμ΄μ μ΄κ±Έ ꡬννλ ν¨ν΄"(?)
- ν©ν 리 λ©μλ ν¨ν΄λ ν
νλ¦Ώ λ©μλ ν¨ν΄μ΄λ€..? (https://refactoring.guru/ko/design-patterns/factory-method)
- μΈμ€ν΄μ€λ₯Ό μμ±νλ λ©μλκ° μΆμλ©μλμ΄κ³ , ν νλ¦Ώ λ©μλκ° λ³λλ‘ μμ
- ν νλ¦Ώ λ©μλ(μμ, λ©μλ, μκ³ λ¦¬μ¦ κ°μ) vs μ λ΅(ꡬμ±, ν΄λμ€, μκ³ λ¦¬μ¦κ΅°)
- μν ν¨ν΄μ "μν"μ "μν μ μ΄"λΌλ κ°λ
μ΄ λ€μ΄κ° μ λ΅ ν¨ν΄μ΄λ€.
- μ λ΅ ν¨ν΄: https://refactoring.guru/ko/design-patterns/strategy
- μν ν¨ν΄: https://refactoring.guru/ko/design-patterns/state
- μ λ€λ₯Έ μν ν΄λμ€μμ λ€λ₯Έ μνλ‘ μ μ΄ν λ 컨ν μ€νΈ κ°μ²΄μμ κ²ν° λ©μλλ₯Ό νΈμΆν΄μ κ°μ Έμ€λμ§? κ·Έλ₯ κ°μ Έμ€λ©΄ μ λλ? : getter, setter
ballMachine.setState(ballMachine.getAState())
ballMachine.setState(ballMachine.AState)
class ballMachin:
State AState;
...
public getAState():
return this.AState