zoukankan      html  css  js  c++  java
  • 自定义中间件实现插拔设计

    设计

    代码不重要,重要的是这个思想

    说白了就是想做到想 注释中间件一样,存在的时候,全局都会走那个中间件,不要用的时候注释掉,除了不实现那个功能之外对全局都不会有影响。

    这就是可插拔式设计

    首先讲解一个模块 importlib

    这个模块的作用:以字符串的形式导入模块

    module = 'file.a'
    importlib.import_module(module)
    上面这句就等于下面这句
    from file import a
    

    接下来就可以讲一下可插拔式设计了。

    现在我想有三种通知方式,短信通知,邮件通知,微信通知,而且我想禁用哪个,就直接禁用哪个,而不用通过去方法里面一个个的注释掉这个函数。

    首先建一个包notify,包里面有四个py文件,init.py email.py msg.py wechat.py

    然后在根目录下写两个py文件 ,一个是 run.py 一个是settings.py

    img

    settings.py

    NOTYFY_LIST = [
        'notify.email.Email',
        'notify.msg.Msg',
        'notify.wechat.WeChat',
    ]
    

    run.py

    import notify
    notify.send_all('hahahaahaha')
    

    email.py

    class Email():
        def __init__(self):
            pass
        def send(self,content):
            print('邮件通知:%s'%content)
    

    msg.py

    class Msg():
        def __init__(self):
            pass
        def send(self,content):
            print('短信通知:%s'%content)
    

    wechat.py

    class WeChat():
        def __init__(self):
            pass
        def send(self,content):
            print('vx通知:%s'%content)
    

    最重要的一个py文件

    import settings
    import importlib
    
    def send_all(content):
        for module_path in settings.NOTYFY_LIST:
            module, class_name = module_path.rsplit('.',maxsplit=1)
            mod = importlib.import_module(module)
            # 上面这句等于from notify import email
            cls = getattr(mod,class_name) #利用反射获取模块种类的变量名
            obj = cls()
            obj.send(content)
    

    总体讲解:

    首先写一个文件夹notify,在这个文件夹里面写了三个py文件,分别用面向对象的方式在每个文件里面写了三个通知的类,每个类都有一个send方法,用来被调用。然后去settings文件里面把这三个类的路径以字符串的形式配置好。

    然后,最重要的一步开始了,在notify文件夹里写了一个__init__.py文件,这就让这个文件夹变成了包。导入这个包的东西,就只用导入这个init就行。前提是在init里面吧那三个py文件导入了先。

    在init 里导入了settings里的配置好的字符串路径,循环这个字符串列表,然后通过这句module, class_name = module_path.rsplit('.',maxsplit=1) 切片,module拿到的就是notify.email ,class_name拿到的就是Email

    然后通过importlib.import_module(module),得到的结果就是那个模块,在这里也就是email模块。 然后又通过反射,获取在这个模块里的类的变量名,用cls来接收,循环的第一次就是 Email这个类,然后obj = cls()实例化生成了一个对象,obj.send(content)就执行了他的方法,打印了一条结果,settings里配置了几个,就打印几个结果。当然我们要运行的文件是 run文件,run里面就只用导入这个包,就相当于导入了这个包的 init 文件,直接notify.send_all('输出我要输入的字符') 就行了。

    这样一来就实现了可插拔式设计,代码不重要,重要的是这个思想。

  • 相关阅读:
    比特币--私钥->公钥->钱包地址
    密码字典收集-
    P2P原理和NAT打洞
    SpringBoot
    Spring核心-IOC-AOP-模版
    ZK典型应用场景
    ZK使用
    [重新做人]从头学习JAVA SE——java.util
    CSVWriter 写 csv文档流程
    SpringBoot的启动流程
  • 原文地址:https://www.cnblogs.com/jie9527-/p/11794210.html
Copyright © 2011-2022 走看看