๋ฐ์ํ
Decorator Pattern
๋ฐ์ฝ๋ ์ดํฐ ํจํด(Decorator Pattern)์ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ๋์ ์ผ๋ก ์ถ๊ฐํ๊ณ ํ์ฅํ ์ ์๋ ํจํด์ ๋๋ค.
- ์ด ํจํด์ ์์์ ์ฌ์ฉํ์ง ์๊ณ ๋ ๊ฐ์ฒด์ ์๋ก์ด ํ๋์ ์ถ๊ฐํ ์ ์๊ฒ ํด์ค๋๋ค.
- ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ฌ๋ฌ ๊ฐ์ ๋ฐ์ฝ๋ ์ดํฐ ๊ฐ์ฒด๋ฅผ ์กฐํฉํ์ฌ ๋ค์ํ ๊ธฐ๋ฅ์ ๋์ ์ผ๋ก ์กฐํฉํ ์ ์๋ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค.
- Decorator Pattern์ Object(๊ฐ์ฒด)๋ฅผ ๊พธ๋ฉฐ์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
- ์ํ๋ ๊ธฐ๋ฅ์ผ๋ก ๊ฐ์ธ์ ์ฌ์ฉํ ์ ์๊ฒ ๋ง๋ค์ด์ฃผ๋ ํจํด ์ ๋๋ค.
class Animal:
def speak(self):
pass
class Cat(Animal):
def speak(self):
print("Meow", end='')
class Dog(Animal):
def speak(self):
print("Bark", end='')
- Animal, Cat, Dog Class๊ฐ ์์ต๋๋ค.
- Cat, Dog๋ ๋ชจ๋ Animal์ ์์ ๋ฐ์ต๋๋ค.
- ์ธ Class ๋ชจ๋ Speak ํจ์๊ฐ ์์ต๋๋ค.
class makeSpace(animal:Animal):
animal.speak()
print(" ")
- makeSpeak ํจ์๋ argument๋ก animal์ ๋ฐ๊ณ ํจ์ ์์์ Animal์ speak๋ฅผ ํธ์ถ ํฉ๋๋ค.
- ์ฌ๊ธฐ์ Cat Object์ธ Kitty๋ฅผ makeSpeak ํจ์๋ก ํธ์ถํ๋ฉด meow ๋ผ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ต๋๋ค.
class Deco(Animal):
def __init__(self, animal:Animal):
self.animals = animal
def speak(self):
self.animals.speak()
- Deco class๋ Animal์ ๊พธ๋ฏธ๋ ์ญํ ๋ก Animal๊ณผ ๋์ผํ interface๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- Animal์์ ์์๋ฐ๊ณ constructor์์ Animal์ property๋ก ๊ฐ์ง๊ณ ์๊ณ speak๋ Animal์ speak ํจ์๋ฅผ ํธ์ถํฉ๋๋ค.
class WthSmile(Deco):
def speak(self):
self.animal.speak()
print(":)", end='')
class WthHeartEyes(Deco):
def speak(self):
self.animal.speak()
print("<3", end='')
- WithSmile๊ณผ WithHeartEyes๋ Deco๋ฅผ ์์๋ฐ๊ณ ๋ถ๋ชจ์ธ Deco ๋ด๋ถ์ ์๋ Animal์์ speak๋ฅผ ํธ์ถํ๊ณ ๊ฐ๊ฐ :), <3์ printํฉ๋๋ค.
Decorator Pattern์ ๊ธฐ์กด์ Object์ ๋ ๋ง์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ ์ํด ๊พธ๋ฏธ๋ ํจํด์ด ํ์ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
Example (Decorator Pattern)
+----------------+
| Display |
+----------------+
| + getColumns() |
| + getRows() |
| + getRowText() |
+----------------+
^
|
+----------------+----------------+
| |
+---------------+ +-----------------+
| StringDisplay | | Deco (Decorator)|
+---------------+ +-----------------+
| - string | | - display |
| + methods | | + methods |
+---------------+ +-----------------+
^
|
+----------------+-----------------+
| |
+-------------+ +-------------+
| SideBorder | | FullBorder |
+-------------+ +-------------+
| - deco | | + methods |
| + methods | +-------------+
+-------------+
class Display:
def getColumns(self):
pass
def getRows(self):
pass
def getRowText(self, row):
pass
def show(self):
n = self.getRows()
for i in range(self.getRows()):
print(self.getRowText(i))
class StringDisplay(Display):
def __init__(self, letters):
self.letters = letters
def getColumns(self):
return len(self.letters)
def getRows(self):
return 1
def getRowText(self, row):
if row == 0:
return self.letters
else:
return -1
class Deco(Display):
def __init__(self, display: Display):
self.display = display
class SideBorder(Deco):
def __init__(self, display, deco):
super().__init__(display)
self.borderDeco = deco
def getColumns(self):
return 1 + self.display.getColumns() + 1
def getRows(self):
return self.display.getRows()
def getRowText(self, row):
return self.borderDeco + self.display.getRowText(row) + self.borderDeco
class FullBorder(Deco):
def __init__(self, display):
super().__init__(display)
def getColumns(self):
return 1 + self.display.getColumns() + 1
def getRows(self):
return 1 + self.display.getRows() + 1
def makeLine(self, deco, count):
buffer = ""
for i in range(count):
buffer += deco
return buffer
def getRowText(self, row):
if row == 0:
return "+" + self.makeLine("-", self.display.getColumns()) + "+"
elif row == (self.display.getRows() + 1):
return "+" + self.makeLine("-", self.display.getColumns()) + "+"
else:
return "|" + self.display.getRowText(row - 1) + "|"
- Client Example 1
# Example usage
b1 = StringDisplay("hello")
b2 = SideBorder(b1, "#")
b3 = FullBorder(b2)
b1.show()
b2.show()
b3.show()
- Client Example Output 1
hello
#hello#
+-------+
|#hello#|
+-------+
- Client Example 2
b1 = StringDisplay("hello, world")
b1 = FullBorder(b1)
b1.show()
- Client Example Output 2
+------------+
|hello, world|
+------------+
- Client Example 3
a = StringDisplay("hello")
a = FullBorder(a)
a = SideBorder(a, "*")
a = FullBorder(a)
a = FullBorder(a)
a = SideBorder(a, "/")
a.show()
- Client Example Output 3
/+-----------+/
/|+---------+|/
/||*+-----+*||/
/||*|hello|*||/
/||*+-----+*||/
/|+---------+|/
/+-----------+/
- Client Example 4
b4 = SideBorder(
FullBorder(
FullBorder(
SideBorder(
FullBorder(
StringDisplay("hello")
), "*"
),
),
"/"
)
)
b4.show()
- Client Example Output 4
/+-----------+/
/|+---------+|/
/||*+-----+*||/
/||*|hello|*||/
/||*+-----+*||/
/|+---------+|/
/+-----------+/
ํฌ๊ณผ์ API
Decorator ํจํด์์๋ Decorator์ Component๋ฅผ ๋์์ ํ๊ณ ์์ต๋๋ค.
- Decorator ํด๋์ค (๋ฐ ๊ทธ ํ์ ํด๋์ค๋ค)๋ Component ํด๋์ค์ ๋์ผํ API๋ฅผ ๊ฐ์ง๋๋ค.
- ์ฅ์์ ์ฌ์ฉํ์ฌ ๋ด์ฉ์ ๊ฐ์ธ๋ API๋ค์ด ๊ฐ์ถ์ด์ง์ง ์๊ณ ๋ค๋ฅธ ํด๋์ค์์ ๋ณผ ์ ์๋๋ฐ, ์ด๊ฒ์ API๊ฐ ํฌ๊ณผ์ ์ด๋ผ๊ณ ํฉ๋๋ค.
- ์ฅ์์ ๋ง์ด ์ฌ์ฉํด์ ํฌํจ์์ผ๋ API๊ฐ ์ ํ ๋ฐ๋์ง ์์์ ์๋ฏธํฉ๋๋ค.
- API๊ฐ ํฌ๊ณผ์ ์ธ ์ด์ ๋ก ์ฌ๊ท์ ๊ตฌ์กฐ๊ฐ ๋ฑ์ฅํ์ต๋๋ค.
- Decorator๊ฐ ๋๋ฌ์ธ๊ณ ์๋ component๋ค์ด ์ค์ ๋ก๋ ๋ค๋ฅธ decorator๊ฐ ๋๋ ๊ตฌ์กฐ ์ ๋๋ค.
- ์ํ๊ป์ง์ ๋ฒ๊ฒจ์ ์๋งน์ด ์ธ์ค ์์์ผ๋, ๊ทธ๊ฒ ๋ํ ๊ป์ง์ธ ๊ฒ๊ณผ ๊ฐ์ ๋ง์ ๋๋ค.
๋์ ์ธ ๊ธฐ๋ฅ ์ถ๊ฐ
- Decorator ํจํด์์ ์ฌ์ฉํ๋ "์์"์ Loose Coupling (๋์จํ ๊ฒฐํฉ)์ด ๋ฉ๋๋ค.
- Tight Coupling (๊ฐํ ๊ฒฐํฉ)์ ํด๋์ค์ ๊ฐ์ฒด๊ฐ ์๋ก ์์กดํ๊ณ ์๋ ์ํ์ ๋๋ค.
- ์ด ์ํ์์๋ ์ผ๋ฐ์ ์ผ๋ก ์ ์ฐ์ฑ๊ณผ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ด ์ค์ด๋ค์ด ์ข์ง ์์ต๋๋ค.
- ๋ฐ๋ผ์, ํ๋ ์์ํฌ์ ์์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ , ์ค๋ธ์ ํธ์ ๊ด๊ณ๋ฅผ ๋ณ๊ฒฝํ ์๋ก์ด ์ค๋ธ์ ํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
๋ฐ์ํ
'๐บ๏ธ Design Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Design Pattern] Bridge Pattern - ๋ธ๋ฆฟ์ง ํจํด (0) | 2024.06.06 |
---|---|
[Design Pattern] Facade Pattern - ํ์ฌ๋ ํจํด (0) | 2024.06.06 |
[Design Pattern] Adapter Pattern - ์ด๋ํฐ ํจํด (0) | 2024.05.27 |
[Design Pattern] Proxy Pattern - ํ๋ก์ ํจํด (0) | 2024.05.27 |
[Design Pattern] Singleton Pattern - ์ฑ๊ธํค ํจํด & Metaclass (0) | 2024.05.21 |