设计模式
2024-12-11
核心思想一般都总结成:关注点分离,依赖反转。
我理解就是:
程序的核心部分是业务逻辑,业务逻辑应该是清晰准确的表达。
业务逻辑应该和实现细节彻底隔离,避免业务逻辑受到实现细节调整的影响。
- 框架隔离:业务逻辑和框架解耦,无论切换到什么框架,业务逻辑无需变化
- UI 隔离:无论使用什么 UI,Web UI 也好,某个图形库也好,命令行也好,业务逻辑无需变化
- 数据库隔离:切换数据库的成本就是封装外围数据操作接口,业务逻辑无需变化
- 外部依赖隔离:外部依赖提供的功能被封装,切换依赖也不会影响到业务逻辑
我就觉得应该通过分层,封装,最终的核心逻辑应该是非常简练的一段代码,就好像把大象装冰箱一样简单:打开冰箱,把大象放进去,关上冰箱。
好处是:
- 代码结构清晰整洁,容易阅读,容易测试,容易维护
- 核心逻辑简单明确,稳定可靠,不容易出严重问题
- 方便调整外部实现,更加灵活
核心概念与实现
-
Entities(实体层)
代表业务核心规则或领域模型,纯粹的对象,不依赖其他层。这一层的职责是定义系统的业务规则,保证其独立性和复用性。
-
Use Cases(用例层)
定义具体的业务流程,协调 Entities 来完成系统的功能需求。这一层负责系统的行为逻辑,并确保业务规则得以正确执行。
-
Interface Adapters(接口适配器层)
负责将外部世界的数据转化为系统可以理解的形式,或者将系统的数据转化为外部需要的形式。这一层包括控制器、Presenter 和 ViewModel。
-
Frameworks & Drivers(框架与驱动层)
最外层,包含数据库、UI、第三方服务等实现细节。它们是可替换的,不影响核心业务逻辑。
实现的三个关键原则
-
依赖规则(Dependency Rule)
依赖只能指向内层,外层不能直接调用内层的实现。通过依赖反转原则(DIP),核心业务逻辑完全摆脱了对实现细节的依赖。
-
边界抽象(Boundary Abstraction)
内层通过接口定义与外层的交互边界,外层实现这些接口。这样,业务逻辑可以独立于外部框架或工具运行。
-
测试友好性(Testability)
因为核心逻辑不依赖外部框架或技术,单元测试可以专注于纯粹的业务逻辑,减少测试复杂度。
PHP 设计模式
2020-08-06
注:这是我在很久以前收藏的一篇文章,来自 IBM Developer,整理资料的时候被翻出来,贴出来算了。
设计模式只是为 Java™ 架构师准备的 —— 至少您可能一直这样认为。实际上,设计模式对于每个人都非常有用。如果这些工具不是 “架构太空人” 的专利,那么它们又是什么?为什么说它们在 PHP 应用程序中非常有用?本文解释了这些问题。
软件设计 设计模式
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),也就是四人帮的意思(因为我们这边的关系,这个词在西方也比较著名,所以...)。
其中定义了设计模式,就是类似的问题的一种解决方案,或者说优秀的设计风格、编码风格,提升代码重用,同时实现高内聚、低耦合,让程序会更加可理解,更加可拓展,更加可维护。
- 一般谈到设计模式,都是在面向对象编程。但是我理解这是一种编程思想,和面向对象并不是强绑定关系。这点需要更多的思考和总结。
- 这里只研究 GoF 的 23 种设计模式,不是说这就是设计模式的全部,这个可能每个人有不同的看法。
- 根据维基百科信息,GoF 后来想重新整理这本书,重新分类,增删一些模式,但是最终没有达成一致。
- 根据维基百科信息,有人认为本书提到的设计模式只是语言特性缺失,在其他语言中,部分模式是不需要的。
- 就好像我们教材上基于 C 语言的数据结构,有部分在现代语言中是不需要开发者去编码实现一样,编译器做的很好了。
六大原则 SOLID
- 单一职责原则(Single Responsibility Principle)
- 开闭原则(Open Closed Principle)
- 里氏替换原则(Liskov Substitution Principle)
- 迪米特法则(Law of Demeter),又叫:最少知识法则(Least Knowledge Principle)
- 接口隔离原则(Interface Segregation Principle)
- 依赖倒置原则(Dependence Inversion Principle)
有些资料中还加入了一个:合成复用原则 Composite/Aggregate Reuse Principle,减少继承,多用聚合。
- https://zhuanlan.zhihu.com/p/110130347
- https://cloud.tencent.com/developer/article/1650116
模式清单
创建型模式 Creational
- 工厂模式 Factory Pattern
- 问题:
- 方案:
- 效果:
- 抽象工厂模式 Abstract Factory Pattern
- 问题:
- 方案:
- 效果:
- 单例模式 Singleton Pattern
- 问题:
- 方案:
- 效果:
- 建造者模式 Builder Pattern
- 问题:
- 方案:
- 效果:
- 原型模式 Prototype Pattern
- 问题:
- 方案:
- 效果:
结构型模式 Structural
- 代理模式 Proxy Pattern
- 问题:
- 方案:
- 效果:
- 适配器模式 Adapter Pattern
- 问题:
- 方案:
- 效果:
- 桥接模式 Bridge Pattern
- 问题:
- 方案:
- 效果:
- 组合模式 Composite Pattern
- 问题:
- 方案:
- 效果:
- 装饰器模式 Decorator Pattern
- 问题:
- 方案:
- 效果:
- 外观模式 Facade Pattern
- 问题:
- 方案:
- 效果:
- 享元模式 Flyweight Pattern
- 问题:
- 方案:
- 效果:
行为型模式 Behavioral
- 责任链模式 Chain of Responsibility Pattern
- 问题:
- 方案:
- 效果:
- 命令模式 Command Pattern
- 问题:
- 方案:
- 效果:
- 解释器模式 Interpreter Pattern
- 问题:
- 方案:
- 效果:
- 迭代器模式 Iterator Pattern
- 问题:
- 方案:
- 效果:
- 中介者模式 Mediator Pattern
- 问题:
- 方案:
- 效果:
- 备忘录模式 Memento Pattern
- 问题:
- 方案:
- 效果:
- 观察者模式 Observer Pattern
- 问题:
- 方案:
- 效果:
- 状态模式 State Pattern
- 问题:
- 方案:
- 效果:
- 策略模式 Strategy Pattern
- 问题:
- 方案:
- 效果:
- 模板模式 Template Pattern
- 访问者模式 Visitor Pattern
参考资料与拓展阅读
软件设计 设计模式
2015-08-10
最经典的是 SOLID 五个,但也有说六个、七个的。
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