ソフトウェアの構成要素は拡張に対しては開いていて、修正に対しては閉じていなければならない。
ソフトウェアの振る舞いは、既存の成果物を変更せず拡張できるようにすべき。
Before
class Order:
def __init__(self) -> None:
self.items = []
self.quantities = []
self.prices = []
self.status = "open"
def add_item(self, name: str, quantity: int, price: int) -> None:
self.items.append(name)
self.quantities.append(quantity)
self.prices.append(price)
def total_price(self) -> int:
total = 0
for i in range(len(self.prices)):
total += self.quantities[i] * self.prices[i]
return total
class PaymentProcessor:
def pay_debit(self, order: Order, security_code: str) -> None:
print("Processing debit payment type")
print(f"Verifying security code: {security_code}")
order.status = "paid"
def pay_credit(self, order: Order, security_code: str) -> None:
print("Processing credit payment type")
print(f"Verifying security code: {security_code}")
order.status = "paid"
order = Order()
order.add_item("Keyboard", 1, 50)
order.add_item("SSD", 1, 150)
order.add_item("USB cable", 2, 5)
print(order.total_price())
processor = PaymentProcessor()
processor.pay_debit(order, "0372846")
After
from abc import ABC, abstractmethod
class Order:
def __init__(self) -> None:
self.items = []
self.quantities = []
self.prices = []
self.status = "open"
def add_item(self, name: str, quantity: int, price: int) -> None:
self.items.append(name)
self.quantities.append(quantity)
self.prices.append(price)
def total_price(self) -> int:
total = 0
for i in range(len(self.prices)):
total += self.quantities[i] * self.prices[i]
return total
class PaymentProcessor(ABC):
@abstractmethod
def pay(self, order: Order, security_code: str) -> None:
pass
class DebitPaymentProcessor(PaymentProcessor):
def pay(self, order: Order, security_code: str) -> None:
print('Processing debit payment type')
print(f'Verifying security code: {security_code}')
order.status = 'paid'
class CreditPaymentProcessor(PaymentProcessor):
def pay(self, order: Order, security_code: str) -> None:
print('Processing debit payment type')
print(f"Verifying security code: {security_code}")
order.status = 'paid'
order = Order()
order.add_item("Keyboard", 1, 50)
order.add_item("SSD", 1, 150)
order.add_item("USB cable", 2, 5)
print(order.total_price())
processor = CreditPaymentProcessor()
processor.pay(order, "0372846")