目 录CONTENT

文章目录

Python设计模式

cplinux98
2022-07-10 / 0 评论 / 0 点赞 / 439 阅读 / 1,268 字 / 正在检测是否收录...

00:文章简介

记录python中2个常用的设计模式:单例模式和工厂模式。

01:单例模式

Singleton Pattern 是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

当你希望在整个系统中,某个类只能出现一个实例时,可以使用单例模式。

class Singleton:
    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = object.__new__(cls)
        return Singleton._instance

obj1 = Singleton()
obj2 = Singleton()
print(obj1, obj2)
# <__main__.Singleton object at 0x10f012d90> <__main__.Singleton object at 0x10f012d90>

这种设计模式在应用程序读取配置文件时很有效果,多个应用程序读取配置文件,只能获取同一份配置文件。

02:工厂模式

工厂模式是一个在软件开发中用来创建对象的设计模式。

在面向对象编程中,术语工厂表示一个负责创建其他类型对象的类

通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法,使用者使用某些参数调用此方法后,工厂会根据需求创建对应的对象,然后将它们返回使用者。

举例:现实生活中我们有造鞋子的工厂,我们需要鞋子的时候,只需要告诉他我要什么样的鞋子,工厂就会给我们造什么样的鞋子,我们并不需要关心造鞋子的过程。

2.1:工厂模式的优点

  • 松耦合,对象的创建独立于类的实现
  • 使用者无需了解创建对象的类,只需要知道需要传递的接口、方法和参数,就能够创建所需要的对象
  • 容易扩展工厂添加其他类型对象的创建,使用者只需要关心参数的变化就可以了

2.2:工厂模式的使用场景

  1. 不知道用户想要创建什么样的对象
  2. 当你想要在创建类与支持创建对象的类(工厂类)之间创建一个可扩展的关联

2.3:示例

  • 工厂中包含

    • 造鞋类

      • Blue和Red,输入大小就可以创造出对应颜色的鞋子
    • 工厂类

      • get_shoes,判断用户想要什么颜色的鞋子,将不同颜色的需求转发到不同的流水线
  • 用户包含

    • 调用工厂类,输入鞋子的颜色和大小,就可以获得对应的鞋子,而不用关心它是怎么产生的

代码

class Blue:
    def __init__(self, size):
        print("This is a pair of blue shoes, size {}".format(size))


class Red:
    def __init__(self, size):
        print("This is a pair of red shoes, size {}".format(size))


class Factory:
    @classmethod
    def get_shoes(cls, colour, size):
        if colour == "Blue":
            return Blue(size)
        if colour == "Red":
            return Red(size)


if __name__ == '__main__':
    factory = Factory()
    shoes = factory.get_shoes("Red", "36")
# This is a pair of red shoes, size 36

03:工厂模式的应用

在收集CMDB资产信息时,一开始需要获取的数据很少,但随着规模的扩大,需要获取的数据越来越多,维护的人越来越多,每个人写的收集代码各个不同,为了统一方法的接口,也为了后续维护人员方便阅读,所以使用了工厂模式+反射+约束来设计收集资产信息的客户端程序。

3.1:程序结构

├── app.py # 主程序
├── lib    # 主程序调用的库,也就是所有接口存放位置
│   ├── __init__.py
│   └── plugins  # 接口文件夹
│       ├── __init__.py
│       ├── basic.py   # 所有接口的基类
│       └── memory.py  # 获取内存信息接口
└── settings.py # 主程序配置文件

3.2:主程序

使用importlib和settings配置文件,动态导入需要的插件接口方法

import importlib
from settings import PLUGIN_CLASS_DICT


def run():
    for key, path in PLUGIN_CLASS_DICT.items():
        module_path, class_name = path.rsplit('.', maxsplit=1)
        module = importlib.import_module(module_path)
        cls = getattr(module, class_name)
        plugin_object = cls()
        info = plugin_object.process()
        print(key, info)


if __name__ == '__main__':
    run()

3.3:配置文件

保存插件的位置和插件的名称

PLUGIN_CLASS_DICT = {
    "memory": "lib.plugins.memory.MemoryPlugin"
}

3.4:接口基类

利用NotImplementedError 约束子类,必须实现process接口方法

class BasePlugin:
    """
    所有插件功能的基类,用于做约束,约束子类中必须实现process功能。
    """
    def process(self):
        raise NotImplementedError()

3.5:接口示例

不管内容如何实现,必须提供process接口返回需要的信息

from .basic import BasePlugin


class MemoryPlugin(BasePlugin):
    """
    采集网卡信息
    """
    def process(self):
        return {'memory': '16G'}

3.6:运行测试

# 返回值
memory {'memory': '16G'}
0

评论区