美文网首页
Better python code(8-?)

Better python code(8-?)

作者: 山猪打不过家猪 | 来源:发表于2023-01-26 16:01 被阅读0次

    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)
    
    • 改进4(Interface隔离):

    10.依赖注入

    相关文章

      网友评论

          本文标题:Better python code(8-?)

          本文链接:https://www.haomeiwen.com/subject/krxshdtx.html