Python设计模式-读书笔记

设计模式

面向对象

对象

封装

多态

继承

抽象

组合

设计规则

不良设计主要表现在4个方面

  • 不动性:以这种方式开发的应用程序非常难以重用。
  • 刚性:以这种方式开发的应用程序,任何小的修改都会导致软件的太多部分必须进行相应的改动,所谓“牵一发而动全身”。
  • 脆弱性:当前应用程序的任何更改都会导致现有系统变得非常容易崩溃。
  • 粘滞性:由于架构层面的修改非常困难,因此修改必须由开发人员在代码或环境本身中进行。

创建型模式

单例模式

1、概念

  • 确保类有且只有一个对象被创建
  • 为对象提供一个访问点,以使程序可以全局访问该对象
  • 控制共享资源的并行访问
  • 所有的模块都是单例

2、基本实现

class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

s_1 = Singleton()
s_2 = Singleton()

print("objected created", s_1)
print("objected created", s_2)

# objected created <__main__.Singleton object at 0x00000137A8ADFF10>
# objected created <__main__.Singleton object at 0x00000137A8ADFF10>

3、懒汉式实例化

# 懒汉式实例化
class Singleton:
    __instance = None
    def __init__(self) -> None:
        if not Singleton.__instance:
            print("__init__ method called..")
        else:
            print("Instance already created:", self.getInstance())
    
    @classmethod
    def getInstance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance

# class initialized, but object not created
s = Singleton()
print("object created", Singleton.getInstance()) #Objcet gets created here

s1 = Singleton() # instance already created


'''
__init__ method called..
__init__ method called..
object created <__main__.Singleton object at 0x00000186165D2190>
Instance already created: <__main__.Singleton object at 0x00000186165D2190>
'''

4、Monostated单例模式

通常程序员需要的是让实例共享相同的状态,而不是同一性

本质是用类变量替换了__dict__

class Borg:
    __shared_state = {}
    def __init__(self) -> None:
        self.x = 1
        self.__dict__ = self.__shared_state

B1 = Borg()
B2 = Borg()
B1.x = 100
print("Borg B1:", B1)
print("Borg B2:", B2)
print("object state B1:", B1.__dict__)
print("object state B2:", B2.__dict__)

"""
Borg B1: <__main__.Borg object at 0x000002E1E7DE4220>
Borg B2: <__main__.Borg object at 0x000002E1E7DE4250>
object state B1: {'x': 100}
object state B2: {'x': 100}
"""

# 使用__new__方法来实现Borg
class Borg2:
    _shared_state = {}
    def __new__(cls, *args, **kwargs) -> Any:
        obj = super(Borg2, cls).__new__(cls, *args, **kwargs)
        obj.__dict__ = cls._shared_state
        return obj

5、通过元类实现单例

# 元组
class MetaSingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwds):
        if cls not in cls._instances:
            cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwds)
        return cls._instances[cls]

class Logger(metaclass=MetaSingleton):
    pass

logger1 = Logger()
logger2 = Logger()
print(logger1)
print(logger2)

"""
<__main__.Logger object at 0x000001A48982A5B0>
<__main__.Logger object at 0x000001A48982A5B0>
"""

6、 demo1

import sqlite3

class MetaSingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class Database(metaclass=MetaSingleton):
    connection = None
    def connect(self):
        if self.connection is None:
            self.connection = sqlite3.connect("db.sqlite3")
            self.cursorobj = self.connection.cursor()
        return self.cursorobj

db1 = Database().connect()
db2 = Database().connect()

print("db1:", db1)
print("db2:", db2)

demo2

class HealthCheck:
    _instance = None
    def __new__(cls, *args, **kwargs):  
        if not HealthCheck._instance:
            HealthCheck._instance = super(HealthCheck, cls).__new__(cls, *args, **kwargs)
        return HealthCheck._instance
    

    def __init__(self) -> None:
        self._servers = []
    
    def addServer(self):
        self._servers.append("Server 1")
        self._servers.append("Server 2")
        self._servers.append("Server 3")
        self._servers.append("Server 4")
    
    def changeServer(self):
        self._servers.pop()
        self._servers.append("Server 5")

hc1 = HealthCheck()
hc2 = HealthCheck()

hc1.addServer()
print("schedule health check for servers (1)...")
for i in range(4):
    print("checking", hc1._servers[i])

hc2.changeServer()
print("schedule health check for servers (2)...")
for i in range(4):
    print("checking", hc2._servers[i])

7、缺点

  • 全局变量可能在某处已经被误改,但是开发人员仍然认为它们没有发生变化,而该变量还在应用程序的其他位置被使用。
  • 可能会对同一对象创建多个引用。由于单例只创建一个对象,因此这种情况下会对同一个对象创建多个引用。
  • 所有依赖于全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类。

工厂模式

1、“工厂”——一个负责创建其他类型对象的类

2、优点

  • 松耦合,即对象的创建可以独立于类的实现
  • 客户端无需了解创建对象的类,但是照样可以使用它来创建对象。它只需要知道需要传递的接口、方法和参数,就能够创建所需类型的对象了。这简化了客户端的实现
  • 可以轻松地在工厂中添加其他类来创建其他类型的对象,而这无需更改客户端代码。最简单的情况下,客户端只需要传递另一个参数就可以了
  • 工厂还可以重用现有对象。但是,如果客户端直接创建对象的话,总是创建一个新对象

3、3种变体

  • 简单工厂模式
    • 允许接口创建对象,但不会暴露对象的创建逻辑
  • 工厂方法模式
    • 允许接口创建对象,但使用哪个类来创建对象,则是交由子类决定的
from abc import ABC, ABCMeta, abstractmethod


class Section(metaclass=ABCMeta):
    @abstractmethod
    def describe(self):
        psdd


class PersonScetion(Section):
    def describe(self):
        print("Personal Section")


class AlbumSection(Section):
    def describe(self):
        print("album Section")


class PatentSection(Section):
    def describe(self):
        print("Patent Section")


class PublicationSection(Section):
    def describe(self):
        print("Publication Section")


class Profile(metaclass=ABCMeta):
    def __init__(self):
        self.sections = []
        self.createProfile()
    
    @abstractmethod
    def createProfile(self):
        pass

    def getSections(self):
        return self.sections
    
    def addSections(self, section):
        self.sections.append(section)

class linkedin(Profile):
    def createProfile(self):
        self.addSections(PersonScetion())
        self.addSections(PatentSection())
        self.addSections(PublicationSection())


class facebook(Profile):
    def createProfile(self):
        self.sections.append(PersonScetion())
        self.sections.append(AlbumSection())


if __name__ == "__main__":
    profile_type= input("[LinkedIn or FaceBook]?")
    profile = eval(profile_type.lower())()
    print("creating profole..", type(profile).__name__)
    print("Profile has sections -- ", profile.getSections())+-
  • 抽象工厂模式
    • 抽象工厂是一个能够创建一系列相关的对象而无需指定/公开其具体类的接口。该模式能够提供其他工厂的对象,在其内部创建其他对象。
from abc import ABCMeta, abstractmethod


class PizzaFactory(metaclass=ABCMeta):

    @abstractmethod
    def cretaeVegPizza(self):
        pass

    @abstractmethod
    def creatNonVegPizza(self):
        pass


class IndiaPizzaFactory(PizzaFactory):
    def cretaeVegPizza(self):
        return DeluxVeggiePizza()
    
    def creatNonVegPizza(self):
        return ChickenPizza()
    

class USPizzaFactory(PizzaFactory):
    def cretaeVegPizza(self):
        return MexicanVegPizza()
    
    def creatNonVegPizza(self):
        return HamPizza()


class VegPizza(metaclass=ABCMeta):
    @abstractmethod
    def prepare(self, VegPizza):
        pass


class NonVegPizza(metaclass=ABCMeta):
    @abstractmethod
    def serve(self, VegPizza):
        pass


class DeluxVeggiePizza(VegPizza):
    def prepare(self):
        print("prepare", type(self).__name__)


class ChickenPizza(NonVegPizza):
    def serve(self, VegPizza):
        print(type(self).__name__, "is served with Chicken on ", type(VegPizza).__name__)


class MexicanVegPizza(VegPizza):
    def prepare(self):
        print("Prepare", type(self).__name__)

class HamPizza(NonVegPizza):
    def serve(self, VegPizza):
        print(type(self).__name__, "is served with Chicken on ", type(VegPizza).__name__)
        

class PizzaStore:
    def __init__(self) -> None:
        pass

    def makePizzas(self):
        for factory in [IndiaPizzaFactory(), USPizzaFactory()]:
            self.factory = factory
            self.NonVegPizza = self.factory.creatNonVegPizza()
            self.vegPizza = self.factory.cretaeVegPizza()
            self.vegPizza.prepare()
            self.NonVegPizza.serve(self.vegPizza)

abcdd = USPizzaFactory()
pizza = PizzaStore()
pizza.makePizzas()

结构型设计模式

1、结构型设计模式

  • 结构型模式描述如何将对象和类组合成更大的结构。
  • 结构型模式是一种能够简化设计工作的模式,因为它能够找出更简单的方法来认识或表示实体之间的关系。在面向对象世界中,实体指的是对象或类。
  • 类模式可以通过继承来描述抽象,从而提供更有用的程序接口,而对象模式则描述了如何将对象联系起来从而组合成更大的对象。结构型模式是类和对象模式的综合体。

门面设计模式

完成了下列事项:

  • 它为子系统中的一组接口提供一个统一的接口,并定义一个高级接口来帮助客户端通过更加简单的方式使用子系统
  • 门面所解决问题是,如何用单个接口对象来表示复杂的子系统。实际上,它并不是封装子系统,而是对底层子系统进行组合
  • 它促进了实现与多个客户端的解耦

这个模式有3个主要的参与者:

  • 门面:门面的主要责任是,将一组复杂导致系统封装起来,从而为外部世界提供一个舒适的外观。
  • 系统:这代表一组不同的子系统,使整个系统混杂在一起,难以观察或使用
  • 客户端:客户端与门面进行交互,这样就可以轻松地与子系统进行通信并完成工作了。不必担心系统的复杂性。
"""
门面设计模式

门面类 EventManager
"""

class EventManager:
    
    def __init(self):
        print("Event Manager:: Let me talk to the folfs \n")

    def arrange(self):
        self.hotelier = Hotelier()
        self.hotelier.bookHotel()

        self.florist = Florist()
        self.florist.setFlowerRequirements()

        self.caterer = Caterer()
        self.caterer.setCuisine()

        self.musician = Musician()
        self.musician.setMusicType()


class Hotelier:
    def __init__(self):
        print("Arranging the Hotel for Marriage? --")

    def __isAvailable(self):
        print("Is the Hotel free for the event on given date?")
        return True
    
    def bookHotel(self):
        if self.__isAvailable():
            print("Registered the booking \n \n")
        

class Florist:
    def __init__(self):
        print("Flower Decorations for the Events? --")

    def setFlowerRequirements(self):
        print("Carnations, Roses and lilies would be used for Decorations \n\n")
    

class Caterer:
    def __init__(self):
        print("Food Arrangements for the Event --")
    
    def setCuisine(self):
        print("Chinese & Continental Cuisine to be served \n\n")
    

class Musician:
    def __init__(self) -> None:
        print("Musical Arrangements for the Marriage --")
    
    def setMusicType(self):
        print("Jazz and Classical will be played\n\n")


class You:
    def __init__(self) -> None:
        print("You:: Whos! Marriage Arrangements??!!!")
    
    def askEventManager(self):
        print("You:: Let's Contact the Event Manager \n\n")
        em = EventManager()
        em.arrange()
    
    def __del__(self):
        print("You:: Thanks to Event Manager, all prearations done!")
    
you = You()
you.askEventManager()

代理模式

在设计模式的上下文中,代理是充当实际对象接口的类。

代理就是封装实际服务对象的包装器或代理人。

代理可以为其包装的对象提供附加功能,而无需更改对象的代码。

代理模式的主要目的是为其他对象提供一个代理者或占位符,从而控制对实际对象的访问。

代理模式可以用于多种场景:

  • 它能够以更简单的方式表示一个复杂的系统。例如,涉及多个复杂计算或过程的系统应该提供一个更简单的接口,让它充当客户端的代理。
  • 它提高了现有的实际对象的安全性。在许多情况下,都不允许客户端直接访问实际对象。这是因为实际对象可能受到恶意活动的危害。这时候,代理就能起到抵御恶意活动的盾牌作用,从而保护了实际的对象。
  • 它为不同服务器上的远程对象提供本地接口。一个明显的例子是客户端希望在远程系统上运行某些命令的分布式系统,但客户端可能没有直接的权限来实现这一点。
  • 它为消耗大量内存的对象提供了一个轻量级的句柄。有时,你可能不想加载主要对象,除非它们真的有必要。
"""
代理
"""

from typing import AsyncGenerator


class Actor:
    def __init__(self) -> None:
        self.is_busy = False
    
    def occuiped(self):
        self.is_busy = True
        print(type(self).__name__, "is occuiped with current movie")
    
    def available(self):
        self.is_busy = False
        print(type(self).__name__, "is free for the movie")
    
    def getStatus(self):
        return self.is_busy
    

class Agent:
    def __init__(self) -> None:
        self.principal = None
        self.actor = Actor()
    
    def work(self):
        if self.actor.getStatus():
            self.actor.occuiped()
        else:
            self.actor.available()


if __name__ == "__main__":
    r = Agent()
    r.work()

代理模式有下述3个主要的参与者:

  • 代理:它维护一个引用,允许代理(Proxy)通过这个引用来访问实际对象。它提供了一个与主题(Subject)相同的接口,以便代理可以替换真实的主题。代理还负责创建和删除真实主题(RealSubject)。
  • 主题:它定义了RealSubject和Proxy的公共接口。以Proxy和RealSubject的形式实现主题(Subject),使用RealSubject的任何地方都可以使用代理(Proxy)
  • 真实主题:它定义代理(Proxy)所代表的真实对象。

从数据结构的角度来看:

  • 代理:它是一个控制对RealSubject类访问的类。它处理客户端的请求,负责创建或删除RealSubject。
  • 主题/真实主题:主题是定义真实主题(RealSubject)和代理(Proxy)相类似的接口。RealSubject是Subject接口的实际实现。它提供了真正的功能,然后由客户端使用。
  • 客户端:它访问要完成工作的Proxy类。Proxy类在内部控制对RealSubject的访问,并引导客户端(Client)所请求的工作。

根据代理的使用方式,我们可以将它们分为虚拟代理、远程代理、保护代理和智能代理。

虚拟代理

如果一个对象实例化后会占用大量内存的话,可以先利用占位符来表示,这就是所谓的虚拟代理。

远程代理

它给位于远程服务器或不同地址空间上的实际对象提供了一个本地表示

保护代理

这种代理能够控制RealSubject的敏感对象的访问。

智能代理

智能代理在访问对象时插入其他操作。

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):

    @abstractmethod
    def do_pay(self):
        pass


class Bank(Payment):
    def __init__(self) -> None:
        self.card = None
        self.account = None

    def __getAccount(self):
        self.account = self.card
        return self.account
    
    def __hasFunds(self):
        print("Bank:: Checking if Account", self.__getAccount(), "has enough funds")
        return True
    
    def setCard(self, card):
        self.card = card
    
    def do_pay(self):
        if self.__hasFunds():
            print("Bank:: Paying the merchant")
            return True
        else:
            print("Bank:: Sorry, not enough funds!")
            return False


class DebitCard(Payment):
    def __init__(self) -> None:
        self.bank = Bank()
    
    def do_pay(self):
        card = input("Proxy:: Punch in Card Number")
        self.bank.setCard(card)
        return self.bank.do_pay


class You:
    def __init__(self) -> None:
        print("You:: Lets buy the Denim shirt")
        self.debitCard = DebitCard()
        self.isPurchased = None
    
    def make_payment(self):
        self.isPurchased = self.debitCard.do_pay()
    
    def __del__(self):
        if self.isPurchased:
            print("You:: Wow! Denim shirt is Mine")
        else:
            print("You:: I should earn more:")


if __name__ == "__main__":
    you = You()
    you.make_payment()

代理模式的优点:

  • 代理可以通过缓存笨重的对象或频繁访问的对象来提高应用程序的性能
  • 代理还提供对于真实主题的访问授权。因此,只有提供合适权限的情况下,这个模式才会接受委派。
  • 远程代理还便于与可用作网络连接和数据库连接的远程服务器进行交互,并可用于监视系统。

行为型模式

观察者模式

观察者模式的主要目标:

  • 它定义了对象之间的一对多的依赖关系,从而使得一个对象中的任何更改都将自动通知给其他依赖对象;
  • 它封装了主题的核心组件。

观察者模式工作场景:

  • 在分布式系统中实现事件服务
  • 用作新闻机构的框架
  • 股票市场
from abc import ABCMeta, abstractmethod
from typing import Any


class NewsPublisher:

    def __init__(self):
        self.__subscribers = []
        self.__latest_news = None
    
    def attach(self, subscriber):
        self.__subscribers.append(subscriber)
    
    def detach(self):
        return self.__subscribers.pop()

    def subscribers(self):
        return [type(sub).__name__ for sub in self.__subscribers]

    def notify_subscribers(self):
        for sub in self.__subscribers:
            sub.update()
    
    def add_news(self, news):
        self.__latest_news = news

    def getNews(self):
        return 'Got News:', self.__latest_news
    

class Subscriber(metaclass=ABCMeta):
    
    @abstractmethod
    def update(self):
        pass


class SMSSubscriber:

    def __init__(self, publisher) -> None:
        self.publisher = publisher
        self.publisher.attach(self)

    def update(self):
        print(type(self).__name__, self.publisher.getNews())
    

class EmailSubscriber:
    
    def __init__(self, publisher) -> None:
        self.publisher = publisher
        self.publisher.attach(self)
    
    def update(self):
        print(type(self).__name__, self.publisher.getNews())
        

class AnyOtherSubscriber:

    def __init__(self, publisher):
        self.publisher = publisher
        self.publisher.attach(self)
    
    def update(self):
        print(type(self).__name__, self.publisher.getNews())
    


if __name__ == '__main__':
    news_publisher = NewsPublisher()
    for subscriber in [SMSSubscriber, EmailSubscriber, AnyOtherSubscriber]:
        subscriber(news_publisher)
        
    print(news_publisher.subscribers)

    news_publisher.add_news("hello world")
    news_publisher.notify_subscribers()

    print("\n Detached:", type(news_publisher.detach()).__name__)
    print("\nSubscribers:", news_publisher.subscribers())
    news_publisher.add_news("second news")
    news_publisher.notify_subscribers()

命令设计模式

命令模式优点:

  • 将调用操作的类与知道如何执行该操作的对象解耦
  • 提供队列系统后,可以创建一系列命令
  • 添加新命令更加容易,并且无需更改现有代码
  • 使用命令模式来定义回滚系统
from abc import ABC, ABCMeta, abstractmethod

class Command(metaclass=ABCMeta):
    
    def __init__(self, recv):
        self.recv = recv
    
    @abstractmethod
    def execute(self):
        pass


class ConcreteCommand(Command):

    def __init__(self, recv):
        self.recv = recv
    
    def execute(self):
        self.recv.action()
    

class Receiver:
    def action(self):
        print("Receiver Action")
    

class Invoker:
    def command(self, cmd):
        self.cmd = cmd
    
    def execute(self):
        self.cmd.execute()
    

if __name__ = '__main__':
    recv = Receiver()
    cmd = ConcreteCommand(recv)
    invoker = Invoker()
    invoker.command(cmd)
    invoker.execute()
from abc import ABCMeta, abstractmethod


class Order(metaclass=ABCMeta):

    @abstractmethod
    def execute(self):
        pass


class BuyStockOrder(Order):

    def __init__(self, stock):
        self.stock = stock
    
    def execute(self):
        self.stock.buy()
    

class SellStockOrder(Order):

    def __init__(self, stock):
        self.stock = stock
    
    def execute(self):
        self.stock.sell()


class StockTrade:

    def buy(self):
        print("you will buy stocks")
    
    def sell(self):
        print("you will sell stocks")
    

class Agent:
    def __init__(self):
        self.__orderQueue = []

    def placeOrder(self, order):
        self.__orderQueue.append(order)
        order.execute()


if __name__ == '__main__':
    # Client
    stock = StockTrade()
    buyStock = BuyStockOrder(stock)
    sellStock = SellStockOrder(stock)

    # Invoker
    agent = Agent()
    agent.placeOrder(buyStock)
    agent.placeOrder(sellStock)

模板设计模式

模板方法模式象适用场景:

  • 当多个算法或类实现类似或相同逻辑的时候;
  • 在子类中实现算法有助于减少重复代码的时候
  • 可以让子类利用覆盖实现行为来定义多个算法的时候

模板方法模式的优点:

  • 没有代码重复
  • 由于模板方法模式使用继承而不是合成,因此能够对代码进行重用。所以,只有为数不多的几个方法需要重写
  • 灵活性允许子类决定如何实现算法中的步骤。
from abc import ABCMeta, abstractmethod


class Trip(metaclass=ABCMeta):

    @abstractmethod
    def setTransport(self):
        pass

    @abstractmethod
    def day1(self):
        pass

    @abstractmethod
    def day2(self):
        pass

    @abstractmethod
    def day3(self):
        pass

    @abstractmethod
    def returnHome(self):
        pass

    def itinerary(self):
        self.setTransport()
        self.day1()
        self.day2()
        self.day3()
        self.returnHome()

    
class VeniceTrip(Trip):
    
    def setTransport(self):
        print("take a boat and find your way in the Grand Canal")
    
    def day1(self):
        print("day1,Venice vist...")
    
    def day2(self):
        print("day2,Venice vist...")
    
    def day3(self):
        print("day3,Venice vist...")
    
    def returnHome(self):
        print("Venice go home")


class MaldiversTrip(Trip):
    
    def setTransport(self):
        print("on foot...")
    
    def day1(self):
        print("day1,Maldivers vist...")
    
    def day2(self):
        print("day2,Maldivers vist...")
    
    def day3(self):
        print("day3,Maldivers vist...")
    
    def returnHome(self):
        print("Maldivers go home")


class TravelAgency:

    def __init__(self) -> None:
        self.trip = None

    def arrangeTrip(self):
        choice = input("Venice or Maldivers?")
        if choice == "Venice":
            self.trip = VeniceTrip()
            self.trip.itinerary()
        if choice == "Maldivers":
            self.trip = MaldiversTrip()
            self.trip.itinerary()


if __name__ == "__main__":
    customer = TravelAgency()
    customer.arrangeTrip()

状态设计模式

状态模式也可以看作是在运行时改变对象行为的一种方式。

状态模式的优点:

  • 在状态设计模式中,对象的行为是其状态的函数结果,并且行为在运行时根据状态而改变
  • 使用状态模式,实现多态行为的好处是显而易见的,并且更易于添加状态来支持额外的行为。
  • 状态设计模式还提高了聚合性,因为特定于状态的行为被聚合到ConcreteState类中,并且放置在代码中的同一个地方
  • 使用状态设计模式,通过只添加一个ConcreteState类来添加行为是非常容易的。因此,状态模式不仅改善了扩展应用程序行为时的灵活性,而且全面提高了代码的可维护性。
from abc import abstractmethod, ABCMeta


class State(metaclass=ABCMeta):

    @abstractmethod
    def Handle(self):
        pass


class ConcreteStateB(State):
    def Handle(self):
        print("Concrete State B")
    

class ConcreteStateA(State):
    
    def Handle(self):
        print("Concrete State A")
    

class Context(State):
    
    def __init__(self):
        self.state = None
    
    def getState(self):
        return self.state
    
    def setState(self, state):
        self.state= state
    
    def Handle(self):
        self.state.Handle()


if __name__ == '__main__':
    context = Context()
    stateA = ConcreteStateA()
    stateB = ConcreteStateB()

    context.setState(stateA)
    context.Handle()

复合模式

复合模式将两个或更多模式组合成解决常见或普遍性问题的解决方案。

MVC模式(模型-试图-控制器模式)

MVC模式的工作机制:

  • 模型提供数据和业务逻辑
  • 视图负责数据的展示
  • 控制器是两者的粘合剂

MVC模式应用场景:

  • 当需要更改展示方式而不更改业务逻辑时
  • 多个控制器可用于使用多个视图来更改用户界面上的展示
  • 当模型改变时,视图无需改动

MVC模式的优点

  • 有助于提高可维护性,强制松耦合,并降低复杂性
  • MVC允许对前端进行独立更改,而对后端逻辑无需任何修改或只需进行很少的更改,因此开发工作仍可以独立运行
  • 可以更改模型或业务逻辑,而无需对视图进行任何更改
  • 可以更改控制器,而不会对视图或模型造成任何影响
class Model:
    services = {
        'emial': {"number": 1000, 'price': 2},
        'sms': {'number': 1000, 'price': 10},
        'voice': {'number': 1000, 'price': 15}
    }


class View:

    def list_services(self, services):
        for svc in services:
            print(svc, " ")
        
    def list_pricing(self, services):
        for svc in services:
            print('For', Model.services[svc]['number'], svc, 'message you pay $', Model.services[svc]['price'])

    
class Controller:
    
    def __init__(self) -> None:
        self.model = Model()
        self.view = View()

    def get_services(self):
        services = self.model.services.keys()
        return self.view.list_services(services)
    
    def get_pricing(self):
        services = self.model.services.keys()
        return self.view.list_pricing(services)



if __name__ == '__main__':
    controller = Controller()
    print("Services Provided:")
    controller.get_services()
    print("Pricing for Services:")
    controller.get_pricing()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容