Python 进阶 — 设计模式

举报
云物互联 发表于 2022/01/19 00:30:14 2022/01/19
【摘要】 目录 文章目录 目录设计模式的原则Interface 模式Adapter 模式单例模式Visitor 模式 设计模式的原则 面向接口编程,而不是面向实现编程。优先使用组合而不是继承。 ...

目录

设计模式的原则

  1. 面向接口编程,而不是面向实现编程。
  2. 优先使用组合而不是继承。

Interface 模式

Python 支持 Duck Typing(鸭子类型)的实现,本质上就是支持面向接口的设计模式。

class Duck:
    def fly(self):
        print("Duck flying")

class Airplane:
    def fly(self):
        print("Airplane flying")

def lift_off(entity):
    entity.fly()

duck = Duck()
plane = Airplane()

lift_off(duck)
lift_off(plane)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Adapter 模式

假设已经实现了 “日志内容的文件写入功能”,现在希望将该功能扩展为将 “日志内容的数据库写入功能”,此时就可以使用 Adapter(适配器)模式,通过实现 db.write 来适配 file.write。

def log(file, msg):
    file.write('[{}] - {}'.format(datetime.now(), msg))

class DBAdapter:
    def __init__(self, db):
        self.db = db

    def write(self, msg):
        self.db.insert(msg)

db_adapter = DBAdapter(db)
log(db_adapter, "sev1 error occurred")

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

可见,只要采用 Adapter 模式,实现了 write 方法,那么不管你是任何对象,都可以进行适配。也算是比较典型的 Duck Typing。但是这种方法的弊端就是,不知道 log 方法的参数类型,想要重构可就难了。

单例模式

单例模式(Singleton Pattern)的实现需要依赖于编程语言对类构造器的隐藏或销毁。

Python 没有提供类似 Java private 关键字的类构造器隐藏机制,但是 Python 可以依靠 Module 机制来实现类构造器的销毁。

#singleton.py

class Singleton:
    def __init__(self):
        self.name = "i'm singleton"

instance = Singleton()

del Singleton  # 把构造函数删除

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用 Singleton:

import singleton

print(singleton.instance.name)  # i'm singleton

instance = Singleton() # NameError: name 'Singleton' is not defined

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

Visitor 模式

Visitor 模式的本质是将数据结构和数据操作进行分离。通过 Python 的 Generator 可以优雅地实现。

class TreeNode:

    def __iter__(self):
        return self.__generator()

    def __generator(self):
        if self.left is not None:
            yield from iter(self.left) 
        yield from self.data

        if self.right is not None:
            yield from iter(self.right) 

root = TreeNode('1')
root.left = TreeNode('2')
root.right = TreeNode('3')

for ele in root:
    print(ele)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

文章来源: is-cloud.blog.csdn.net,作者:云物互联,版权归原作者所有,如需转载,请联系作者。

原文链接:is-cloud.blog.csdn.net/article/details/122541891

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。