一网打尽、详解面试最常被问到的几种 Python 设计模式(1)

本文介绍了Python中常见的设计模式,包括单例模式的实现,确保多线程环境下实例的唯一性,以及工厂模式的简单工厂、工厂方法和抽象工厂的运用。此外,还详细阐述了构建者模式,通过实例展示了如何一步步构建一个复杂对象。这些设计模式在实际编程和面试中具有重要价值。
摘要由CSDN通过智能技术生成

“”"

_instance = {}

def _singleton(*args, **kargs):

if cls not in _instance:

_instance[cls] = cls(*args, **kargs)

return _instance[cls]

return _singleton

使用上面装饰器的类,构建的实例都能保证单例存在

@singleton

class Singleton(object):

“”“单例实例”“”

def init(self, arg1):

self.arg1 = arg1

使用方式如下:

if name == ‘main’:

instance1 = Singleton(“xag”)

instance2 = Singleton(“xingag”)

print(id(instance1))

print(id(instance2))

需要注意的是,上面 2 种方式创建的单例并不适用于多线程

要保证多线程中构建的实例对象为单例,需要在 __new__ 函数中使用 threading.Lock() 加入同步锁

class Singleton(object):

“”"

实例化一个对象

“”"

_instance_lock = threading.Lock()

def init(self):

pass

def new(cls, *args, **kwargs):

if not hasattr(Singleton, “_instance”):

with Singleton._instance_lock:

if not hasattr(Singleton, “_instance”):

Singleton._instance = object.new(cls)

return Singleton._instance

使用的时候,在线程任务中实例化对象,运行线程即可

def task(arg):

“”"

任务

:param arg:

:return:

“”"

instance = Singleton()

print(id(instance), ‘\n’)

if name == ‘main’:

3个线程

for i in range(3):

t = threading.Thread(target=task, args=[i, ])

t.start()

这样,就保证了多线程创建的实例是单例存在的,不会导致脏数据!

2. 工厂模式


以生产3种水果对象为例,定义 3 类水果,分别是:苹果、香蕉、橘子

定义一系列水果

class Apple(object):

“”“苹果”“”

def repr(self):

return “苹果”

class Banana(object):

“”“香蕉”“”

def repr(self):

return “香蕉”

class Orange(object):

“”“橘子”“”

def repr(self):

return “橘子”

工厂模式包含:简单工厂、工厂方法、抽象工厂

第 1 种,简单工厂

简单工厂是最常见的工厂模式,适用于简单的业务场景

首先,定义一个工厂类,创建一个静态方法,根据输入的类型,返回不同的对象

class FactorySimple(object):

“”“简单工厂模式”“”

@staticmethod

def get_fruit(fruit_name):

if ‘a’ == fruit_name:

return Apple()

elif ‘b’ == fruit_name:

return Banana()

elif ‘o’ == fruit_name:

return Orange()

else:

return ‘没有这种水果’

使用方式如下:

if name == ‘main’:

分别获取3种水果

输入参数,通过简单工厂,返回对应的实例

instance_apple = FactorySimple.get_fruit(‘a’)

instance_banana = FactorySimple.get_fruit(‘b’)

instance_orange = FactorySimple.get_fruit(‘o’)

第 2 种,工厂方法

工厂方法将创建对象的工作让相应的工厂子类去实现,保证在新增工厂类时,不用修改原有代码

首先,创建一个抽象公共工厂类,并定义一个生产对象的方法

import abc

from factory.fruit import *

class AbstractFactory(object):

“”“抽象工厂”“”

metaclass = abc.ABCMeta

@abc.abstractmethod

def get_fruit(self):

pass

接着,创建抽象工厂类的 3 个子类,并重写方法,创建一个实例对象并返回

class AppleFactory(AbstractFactory):

“”“生产苹果”“”

def get_fruit(self):

return Apple()

class BananaFactory(AbstractFactory):

“”“生产香蕉”“”

def get_fruit(self):

return Banana()

class OrangeFactory(AbstractFactory):

“”“生产橘子”“”

def get_fruit(self):

return Orange()

最后的使用方式如下:

if name == ‘main’:

每个工厂负责生产自己的产品也避免了我们在新增产品时需要修改工厂的代码,而只要增加相应的工厂即可

instance_apple = AppleFactory().get_fruit()

instance_banana = BananaFactory().get_fruit()

instance_orange = OrangeFactory().get_fruit()

print(instance_apple)

print(instance_banana)

print(instance_orange)

第 3 种,抽象工厂

如果一个工厂要生产多个产品,使用工厂方法的话,就需要编写很多工厂类,不太实用,使用抽象工厂就可以很好的解决这个问题

以川菜馆和湘菜馆炒两个菜,毛血旺和小炒肉为例

首先,创建川菜毛血旺、川菜小炒肉、湘菜毛血旺、湘菜小炒肉 4 个类

class MaoXW_CC(object):

“”“川菜-毛血旺”“”

def str(self):

return “川菜-毛血旺”

class XiaoCR_CC(object):

“”“川菜-小炒肉”“”

def str(self):

return “川菜-小炒肉”

class MaoXW_XC(object):

“”“湘菜-毛血旺”“”

def str(self):

return “湘菜-毛血旺”

class XiaoCR_XC(object):

“”“湘菜-小炒肉”“”

def str(self):

return “湘菜-小炒肉”

然后,定义一个抽象工厂类,内部定义两个方法,可以生成毛血旺和小炒肉

class AbstractFactory(object):

“”"

抽象工厂

既可以生产毛血旺,也可以生成小炒肉

“”"

metaclass = abc.ABCMeta

@abc.abstractmethod

def product_maoxw(self):

pass

@abc.abstractmethod

def product_xiaocr(self):

pass

接着,创建抽象工厂类的两个子类,川菜工厂和湘菜工厂,重写方法,然后创建对应的实例对象返回

class CCFactory(AbstractFactory):

“”“川菜馆”“”

def product_maoxw(self):

return MaoXW_CC()

def product_xiaocr(self):

return XiaoCR_CC()

class XCFactory(AbstractFactory):

“”“湘菜馆”“”

def product_maoxw(self):

return MaoXW_XC()

def product_xiaocr(self):

return XiaoCR_XC()

最后,使用川菜工厂和湘菜工厂分别炒两个菜

if name == ‘main’:

川菜炒两个菜,分别是:毛血旺和小炒肉

maoxw_cc = CCFactory().product_maoxw()

xiaocr_cc = CCFactory().product_xiaocr()

print(maoxw_cc, xiaocr_cc)

maoxw_xc = XCFactory().product_maoxw()

xiaocr_xc = XCFactory().product_xiaocr()

print(maoxw_xc, xiaocr_xc)

3. 构建者模式


构建者模式,是将一个复杂对象的构造与表现进行分离,利用多个步骤进行创建,同一个构建过程可用于创建多个不同的表现

简单来说,就是将一个复杂对象实例化的过程,按照自己的想法,一步步设置参数,定制一个我们需要的对象

构建者模式一般由 Director(指挥官)和 Builder(建设者)构成

其中:

Builder 用于定义目标对象部件的方法和参数

Director 用于构造一个 Builder 的接口,由 Director 去指导 Builder 生成一个复杂的对象

以购买一辆车( 包含:准备钱、看车、试驾、购买 4 个步骤)为例

首先,定义一个车的实体,并定义属性变量

class Car(object):

def init(self):

准备的钱

self.money = None

去哪里看车

self.address = None

试驾什么车

self.car_name = None

购买时间是

self.buy_time = None

def str(self):

return “准备了:%s,去%s看车,试驾了%s,下单了,购买时间是:%s” % (self.money, self.address, self.car_name, self.buy_time

然后,创建一个 Builder,实例化一个 Car 对象;针对上面 4 个步骤,通过定义 4 个方法

分别是:准备多少钱、去哪里看车、试驾什么车、下单购买的时间

创建者

class CarBuilder(object):

def init(self):

self.car = Car()

def ready_money(self, money):

“”"

准备的金额

:param money:

:return:

“”"

self.car.money = money

sleep(0.5)

return self

def see_car(self, address):

“”"

去哪里看车

:param address:

:return:

“”"

self.car.address = address

sleep(0.5)

return self

def test_drive(self, car_name):

“”"

试驾了什么车

:param car_name:

:return:

“”"

self.car.car_name = car_name

sleep(0.5)

return self

def buy_car(self, buy_time):

“”"

下单时间

:param buy_time:

:return:

“”"

self.car.buy_time = buy_time

sleep(0.5)

return self

接着,创建 Director,创建 build 方法,使用 Builder 一步步构建一个车对象并返回

class Director(object):

def init(self):

self.builder = None

def build(self, builder):

self.builder = builder

self.builder. \

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

builder. \

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-uVnscSac-1712980921356)]

[外链图片转存中…(img-2CTIJake-1712980921357)]

[外链图片转存中…(img-aR0wdc5r-1712980921357)]

[外链图片转存中…(img-S7zuaTHa-1712980921357)]

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值