#4 转载:五种常见的 PHP 设计模式
PHP 设计模式 2020-08-06注:这是我在很久以前收藏的一篇文章,来自 IBM Developer,整理资料的时候被翻出来,贴出来算了。
设计模式只是为 Java™ 架构师准备的 —— 至少您可能一直这样认为。实际上,设计模式对于每个人都非常有用。如果这些工具不是 “架构太空人” 的专利,那么它们又是什么?为什么说它们在 PHP 应用程序中非常有用?本文解释了这些问题。
coding in a complicated world
注:这是我在很久以前收藏的一篇文章,来自 IBM Developer,整理资料的时候被翻出来,贴出来算了。
设计模式只是为 Java™ 架构师准备的 —— 至少您可能一直这样认为。实际上,设计模式对于每个人都非常有用。如果这些工具不是 “架构太空人” 的专利,那么它们又是什么?为什么说它们在 PHP 应用程序中非常有用?本文解释了这些问题。
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),也就是四人帮的意思(因为我们这边的关系,这个词在西方也比较著名,所以...)。
其中定义了设计模式,就是类似的问题的一种解决方案,或者说优秀的设计风格、编码风格,提升代码重用,同时实现高内聚、低耦合,让程序会更加可理解,更加可拓展,更加可维护。
有些资料中还加入了一个:合成复用原则 Composite/Aggregate Reuse Principle,减少继承,多用聚合。
最经典的是 SOLID 五个,但也有说六个、七个的。
我个人比较喜欢的方式,简单高效。
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