8.SOFTWARE ARCHITECTURE in Python
import tkinter as tk
import uuid
import string
import random
from abc import ABC, abstractmethod
# functional strategy
def generate_uuid1():
return uuid.uuid1()
def generate_uuid4():
return uuid.uuid4()
def generate_simple_id():
return ''.join(random.choices(string.ascii_lowercase, k=30))
class Model:
def __init__(self):
self.uuid = []
class Controller:
def __init__(self, model, view, generate_uuid):
self.model = model
self.view = view
self.generate_uuid = generate_uuid
def start(self):
self.view.setup(self)
self.view.start_main_loop()
def handle_click_generate_uuid(self):
# generate a uuid and add it to the list
self.model.uuid.append(self.generate_uuid())
self.view.append_to_list(self.model.uuid[-1])
def handle_click_clear_list(self):
# clear the uuid list in the model and the view
self.model.uuid = []
self.view.clear_list()
class View(ABC):
@abstractmethod
def setup(self, controller):
pass
@abstractmethod
def append_to_list(self, item):
pass
@abstractmethod
def clear_list(self):
pass
@abstractmethod
def start_main_loop(self):
pass
class TkView(View):
def setup(self, controller):
# setup tkinter
self.root = tk.Tk()
self.root.geometry("400x400")
self.root.title("UUIDGen")
# create the gui
self.frame = tk.Frame(self.root)
self.frame.pack(fill=tk.BOTH, expand=1)
self.label = tk.Label(self.frame, text="Result:")
self.label.pack()
self.list = tk.Listbox(self.frame)
self.list.pack(fill=tk.BOTH, expand=1)
self.generate_uuid_button = tk.Button(self.frame, text="Generate UUID", command=controller.handle_click_generate_uuid)
self.generate_uuid_button.pack()
self.clear_button = tk.Button(self.frame, text="Clear list", command=controller.handle_click_clear_list)
self.clear_button.pack()
def append_to_list(self, item):
self.list.insert(tk.END, item)
def clear_list(self):
self.list.delete(0, tk.END)
def start_main_loop(self):
# start the loop
self.root.mainloop()
# create the MVC & start the application
c = Controller(Model(), TkView(), generate_simple_id)
c.start()
9.SOLID
- 我写的订单支付系统:可以看出,添加,支付,计算,全都放在了一个Order类中
class Order:
"""
订单支付系统
"""
def __init__(self):
self.items = []
self.quantities = []
self.prices = []
self.status = "open"
def add_item(self,name,quantity,price):
"""
给购物车中添加商品
"""
self.items.append(name)
self.quantities.append(quantity)
self.prices.append(price)
def total_price(self):
"""
计算总价
"""
total = 0
for i in range(len(self.prices)):
total += self.quantities[i]*self.prices[i]
return total
def pay(self,payment_type,security_code):
"""
手动传入支付类型,在进行判断,然后支付
"""
if payment_type =="debit":
print("Processing debit payment type")
print(f"Verifying security code:{security_code}")
self.status = "paid"
elif payment_type == "credit":
print("Processing credit payment type")
print(f"Verifying security code:{security_code}")
self.status = "paid"
else:
raise Exception(f"Unknow payment type:{payment_type}")
order = Order()
order.add_item("keyborad",1,50)
order.add_item("SSD",2,1000)
order.add_item("USB",5,25)
print(order.total_price())
order.pay("debit","098")
- 改进1(single):将支付从Oder类里面分离,其次就是,不能用字符串和if来判断,万一以后增加了alipay,paypal之类的方式,每次都要找到该方法,然后添加if判断,这样是不行的
class PaymentProcessor:
def pay_debit(self,order:Order,security_code:str):
print("Processing debit payment type")
print(f"Verifying security code:{security_code}")
order.status = "paid"
def pay_credit(self,security_code):
print("Processing credit payment type")
print(f"Verifying security code:{security_code}")
order.status = "paid"
order = Order()
order.add_item("keyborad",1,50)
order.add_item("SSD",2,1000)
order.add_item("USB",5,25)
print(order.total_price())
processor = PaymentProcessor()
processor.pay_debit(order,"098")
- 改进2(Open):开放封闭原则,即我们要添加新的功能时候,最好是不要去修改原来的类,比如我们现在要添加额外的支付方式,aliPay,paypal的话我们必须去修改PaymenProcessor,这样违反了开闭原则;我们可以将这个类抽象成为一个接口类,然后用不用的支付方式来继承这个接口类,实现子类的不同方式的支付
class PaymentProcessor(ABC):
@abstractmethod
def pay(self,order,security_code):
pass
class DebitPaymentProcessor(PaymentProcessor):
def pay(self,order,security_code):
print("Processing debit payment type")
print(f"Verifying security code:{security_code}")
order.status = "paid"
class CreditPaymentProcessor(PaymentProcessor):
def pay(self,order,security_code):
print("Processing credit payment type")
print(f"Verifying security code:{security_code}")
order.status = "paid"
class PayPalPaymentProcessor(PaymentProcessor):
def pay(self,order,security_code):
print("Processing PayPal payment type")
print(f"Verifying security code:{security_code}")
order.status = "paid"
order = Order()
order.add_item("keyborad",1,50)
order.add_item("SSD",2,1000)
order.add_item("USB",5,25)
print(order.total_price())
processor = CreditPaymentProcessor()
processor.pay(order,"098")
- 改进3(liskov替换):假设PayPal不在是使用security_code验证,而是使用email地址,那么上面的方法就不适用了
class PaymentProcessor(ABC):
@abstractmethod
def pay(self,order):
pass
class DebitPaymentProcessor(PaymentProcessor):
def __init__(self,security_code) -> None:
self.security_code = security_code
def pay(self,order,):
print("Processing debit payment type")
print(f"Verifying security code:{self.security_code}")
order.status = "paid"
class CreditPaymentProcessor(PaymentProcessor):
def __init__(self,security_code) -> None:
self.security_code = security_code
def pay(self,order):
print("Processing credit payment type")
print(f"Verifying security code:{self.security_code}")
order.status = "paid"
class PayPalPaymentProcessor(PaymentProcessor):
def __init__(self,email_adress) -> None:
self.email_adress = email_adress
def pay(self,order):
print("Processing PayPal payment type")
print(f"Verifying security code:{self.email_adress}")
order.status = "paid"
order = Order()
order.add_item("keyborad",1,50)
order.add_item("SSD",2,1000)
order.add_item("USB",5,25)
print(order.total_price())
processor = CreditPaymentProcessor("098")
processor.pay(order)
10.依赖注入
网友评论