#4 转载:五种常见的 PHP 设计模式

2020-08-06

注:这是我在很久以前收藏的一篇文章,来自 IBM Developer,整理资料的时候被翻出来,贴出来算了。
设计模式只是为 Java™ 架构师准备的 —— 至少您可能一直这样认为。实际上,设计模式对于每个人都非常有用。如果这些工具不是 “架构太空人” 的专利,那么它们又是什么?为什么说它们在 PHP 应用程序中非常有用?本文解释了这些问题。

#3 23 种设计模式

2019-05-26

什么是设计模式

https://en.wikipedia.org/wiki/Design_Patterns
https://en.wikipedia.org/wiki/Software_design_pattern

我们说的 23 中设计模式,是来自一本 1994 年出版的书:《Design Patterns: Elements of Reusable Object-Oriented Software》。
这本书的中文名字叫:《设计模式:可复用面向对象软件的基础》。
写这本书的四位作者,被人成为 GoF(Gang of Four),也就是四人帮的意思(因为我们这边的关系,这个词在西方也比较著名,所以...)。

其中定义了设计模式,就是类似的问题的一种解决方案,或者说优秀的设计风格、编码风格,提升代码重用,同时实现高内聚、低耦合,让程序会更加可理解,更加可拓展,更加可维护。

  1. 一般谈到设计模式,都是在面向对象编程。但是我理解这是一种编程思想,和面向对象并不是强绑定关系。这点需要更多的思考和总结。
  2. 这里只研究 GoF 的 23 种设计模式,不是说这就是设计模式的全部,这个可能每个人有不同的看法。
  3. 根据维基百科信息,GoF 后来想重新整理这本书,重新分类,增删一些模式,但是最终没有达成一致。
  4. 根据维基百科信息,有人认为本书提到的设计模式只是语言特性缺失,在其他语言中,部分模式是不需要的。
    1. 就好像我们教材上基于 C 语言的数据结构,有部分在现代语言中是不需要开发者去编码实现一样,编译器做的很好了。

六大原则 SOLID

  1. 单一职责原则(Single Responsibility Principle)
  2. 开闭原则(Open Closed Principle)
  3. 里氏替换原则(Liskov Substitution Principle)
  4. 迪米特法则(Law of Demeter),又叫:最少知识法则(Least Knowledge Principle)
  5. 接口隔离原则(Interface Segregation Principle)
  6. 依赖倒置原则(Dependence Inversion Principle)

有些资料中还加入了一个:合成复用原则 Composite/Aggregate Reuse Principle,减少继承,多用聚合。

  • https://zhuanlan.zhihu.com/p/110130347
  • https://cloud.tencent.com/developer/article/1650116

模式清单

创建型模式 Creational

  1. 工厂模式 Factory Pattern
  2. 问题:
  3. 方案:
  4. 效果:
  5. 抽象工厂模式 Abstract Factory Pattern
  6. 问题:
  7. 方案:
  8. 效果:
  9. 单例模式 Singleton Pattern
  10. 问题:
  11. 方案:
  12. 效果:
  13. 建造者模式 Builder Pattern
  14. 问题:
  15. 方案:
  16. 效果:
  17. 原型模式 Prototype Pattern
  18. 问题:
  19. 方案:
  20. 效果:

结构型模式 Structural

  1. 代理模式 Proxy Pattern
  2. 问题:
  3. 方案:
  4. 效果:
  5. 适配器模式 Adapter Pattern
  6. 问题:
  7. 方案:
  8. 效果:
  9. 桥接模式 Bridge Pattern
  10. 问题:
  11. 方案:
  12. 效果:
  13. 组合模式 Composite Pattern
  14. 问题:
  15. 方案:
  16. 效果:
  17. 装饰器模式 Decorator Pattern
  18. 问题:
  19. 方案:
  20. 效果:
  21. 外观模式 Facade Pattern
  22. 问题:
  23. 方案:
  24. 效果:
  25. 享元模式 Flyweight Pattern
  26. 问题:
  27. 方案:
  28. 效果:

行为型模式 Behavioral

  1. 责任链模式 Chain of Responsibility Pattern
  2. 问题:
  3. 方案:
  4. 效果:
  5. 命令模式 Command Pattern
  6. 问题:
  7. 方案:
  8. 效果:
  9. 解释器模式 Interpreter Pattern
  10. 问题:
  11. 方案:
  12. 效果:
  13. 迭代器模式 Iterator Pattern
  14. 问题:
  15. 方案:
  16. 效果:
  17. 中介者模式 Mediator Pattern
  18. 问题:
  19. 方案:
  20. 效果:
  21. 备忘录模式 Memento Pattern
  22. 问题:
  23. 方案:
  24. 效果:
  25. 观察者模式 Observer Pattern
  26. 问题:
  27. 方案:
  28. 效果:
  29. 状态模式 State Pattern
  30. 问题:
  31. 方案:
  32. 效果:
  33. 策略模式 Strategy Pattern
  34. 问题:
  35. 方案:
  36. 效果:
  37. 模板模式 Template Pattern
    • 问题:
    • 方案:
    • 效果:
  38. 访问者模式 Visitor Pattern
    • 问题:
    • 方案:
    • 效果:

参考资料与拓展阅读

#1 Python 单例模式

2015-04-06

使用全局变量

我个人比较喜欢的方式,简单高效。

class Application:
    pass

APP = Application()

装饰器(使用特定方法来获取对象实例)

import threading

class singleton:
    _instance_lock = threading.Lock()

    def __init__(self, decorated):
        self._decorated = decorated

    def instance(self):
        if not hasattr(self, '_instance'):
            with singleton._instance_lock:
                if not hasattr(self, '_instance'):
                    self._instance = self._decorated()
        return self._instance

    def __call__(self):
        raise TypeError('Singletons must be accessed through `instance()`.')

    def __instancecheck__(self, inst):
        return isinstance(inst, self._decorated)

    def __getattr__(self, name):
        if name == '_instance':
            raise AttributeError("'singleton' object has no attribute '_instance'")
        return getattr(self.instance(), name)

@singleton
class Application:
    pass

Application.instance()

装饰器

def singleton(cls):
    _instances = {}

    def _inner(*args, **kargs):
        if cls not in _instances:
            _instances[cls] = cls(*args, **kargs)
        return _instances[cls]

    return _inner

元类

class Application:
    _instance_lock = threading.Lock()

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

改成通用方式:

import threading

class SingletonMeta(type):
    _instances = {}
    _instance_lock = threading.Lock()

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            with cls._instance_lock:
                if cls not in cls._instances:
                    instance = super().__call__(*args, **kwargs)
                    cls._instances[cls] = instance
        return cls._instances[cls]

class Application(metaclass=SingletonMeta):
    pass