设计模式,学习 软件工程 的一些规范和前人的总结
参考
注册表(Registry)
我们写代码的时候经常写出 大量的 if-elif 不利于后续维护性的代码
扩展性很差,修改代码会破坏结构,耦合度太高了,比如下面的代码
def cmd_start():
print("Starting service...")
def cmd_stop():
print("Stopping service...")
def cmd_restart():
print("Restarting service...")
def handle_command(cmd: str):
"""根据命令字符串选择对应函数执行(非注册表版)"""
if cmd == "start":
cmd_start()
elif cmd == "stop":
cmd_stop()
elif cmd == "restart":
cmd_restart()
else:
print("Unknown command:", cmd)
if __name__ == "__main__":
handle_command("start")
handle_command("stop")
handle_command("restart")
handle_command("status") # 未知命令
聪明的你很快就想到了使用 Dict 存放,采用 Key-Val 的方式,这样就能最低限度的侵入性
注册表模式的核心思想是:把某一类对象统一注册到一个中心容器中,通过字符串或键来访问它们,而不是硬编码依赖。
def cmd_start():
print("Starting service...")
def cmd_stop():
print("Stopping service...")
def cmd_restart():
print("Restarting service...")
FUNC_MAP: dict[str, callable] = {
"start": cmd_start,
"restart": cmd_restart,
"stop": cmd_stop
}
def handle_command(cmd: str):
"""根据命令字符串选择对应函数执行(非注册表版)"""
for key, func in FUNC_MAP.items():
if cmd == key:
func()
return
print("Unknown command:", cmd)
if __name__ == "__main__":
handle_command("start")
handle_command("stop")
handle_command("restart")
handle_command("status") # 未知命令
我们更进一步,使用 python装饰器 的特性,就得出了注册表(Registry) 了
# 1. 定义一个全局注册表
COMMAND_REGISTRY: dict[str, callable] = {}
# 2. 定义一个装饰器,用来把函数注册进去
def register_command(name: str):
def decorator(func):
COMMAND_REGISTRY[name] = func
return func # 返回原函数,便于正常调用/测试
return decorator
# 3. 各个命令通过装饰器注册自己
@register_command("start")
def cmd_start():
print("Starting service...")
@register_command("stop")
def cmd_stop():
print("Stopping service...")
@register_command("restart")
def cmd_restart():
print("Restarting service...")
# 4. 统一的命令处理入口
def handle_command(cmd: str):
func = COMMAND_REGISTRY.get(cmd)
if func is None:
print("Unknown command:", cmd)
else:
func()
if __name__ == "__main__":
handle_command("start")
handle_command("stop")
handle_command("restart")
handle_command("status") # 未知命令
各大出名的开源框架,比如 fastapi的路由注册,pytorch的模型注册,插件注册都使用的是 Registry设计模式;这种设计模式非常非常适合写 plug-in