Python设计模式-读书笔记

2021-06-25  本文已影响0人  静赏月之美

设计模式

面向对象

对象

封装

多态

继承

抽象

组合

设计规则

不良设计主要表现在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个主要的参与者:

从数据结构的角度来看:

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

虚拟代理

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

远程代理

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

保护代理

这种代理能够控制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()

状态设计模式

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

状态模式的优点:

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模式的优点

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()

上一篇下一篇

猜你喜欢

热点阅读