foreach ($GLOBALS['hooks'][$eventName] as $callback) {
$callback($eventName, $data);
}
}
如你所见,它们都遵循传递者模式(Mediator Pattern),并且被设计为从sender中解耦caller,所以都是面向对象的。都提供状态、都是模块化的。不同点在于:第一个是通过传统的类实现的(因此可重用,这也是使用类的一个优势),而第二个使用了全局变量,并不可重用。我在这里使用“hook”,这是一个Drupal使用的事件系统。
Drupal是一个很好的例子,它的模块系统、“hook”系统、结构系统都是面向对象的,但都不是使用对象实现的,它是使用函数和动态分配,这导致了很多尴尬的折中,我并不是说这是一个好的面向对象,只是证明类并不是面向对象编程所必须的因素。
为什么这很重要?
很简单,因为很多开发者认为他们使用了类就是在做面向对线编程;另一些人认为他们使用函数就是在做过程式编程了,这并不正确。过程式编程和面向对象编程都是一种写代码的途径,而不是你写代码的手段。你会遵循步骤,按照设定好的方式去编写程序吗?你看起来是在函数式编程,但是如果你专注于状态改变和密封抽象,你就是在用面向对象编程。
类只是帮助简化面向对象编程的工具,并不是面向对象编程的要求或指示器。
面向对象编程与数据库存取
那面向对象编程里的数据库存取又是什么样的呢?面向对象编程的数据库存取是完全抽象的,我的方法是:
$mapper = new PersonDataMapper(new MySQLi(...));
$people = $mapper->getAll();
people是一个person对象的数组。注意:像这样抽象很有必要,所以事物对象无法直接对数据库操作,你需要一个映射器来翻译事物对象和数据存储之间的转换。一个专门的映射器会在内部创建请求,执行并返回结果。但这完全是抽象的,我们可以简单地换掉映射器来改变数据库层实现细节。
数据持久化的责任变成了封装抽象,这也就是为什么它是面向对象编程而不是过程式编程。