首先,我建议退后一步,了解面向对象的全部内容。创造了“面向对象编程”一词的艾伦·凯曾这样描述它:
我认为对象就像网络上的生物细胞和/或个人计算机,只能与消息通信。
(资源)
在 PHP(以及大多数面向对象的语言)中,这些消息通常是方法调用,或者在公共属性的情况下,获取和设置它们的值。
因此,将系统中的对象视为更大有机体中的单个细胞,它们协作以实现更大的目标,而不是试图将您需要的所有行为混合到一个对象中。
这是一个很大的话题,已经写了很多书,但是就您在问题中提到的对象而言,我将首先对它们所属的不同类别进行区分。可以将数据库或会话对象视为一种“服务”类型,其他对象(例如您的控制器,如果您使用 MVC 框架)将依赖它。正如其他人所提到的,依赖注入是处理此类服务的一个很好的解决方案,但在大多数情况下,我不建议将它用于像 User 类这样的东西,每个用户应该有一个实例(当然不是字面意思 - 你'd 只会将特定的用户对象加载到您需要处理特定请求的内存中,在许多情况下只是当前用户的实例)。
要了解有关依赖注入的更多信息,我推荐这篇文章Martin Fowler 创造了这个术语,并且他在其中提到了一个更简单的依赖注入容器替代方案,称为服务定位器。
(依赖注入容器方法更健壮但也更复杂;幸运的是,它有一个很好的开源库)。
用户、文章和类别都是CMS中域对象的示例。这些是 MVC(也称为域模型)的“M”(模型)的一部分。当然,您仍然需要一种将这些对象进出数据库的方法,因此您可能还需要某种 Repository 或 Query 类(可以将 Repository 类视为一种服务)。并非所有 PHP 系统都有真正的域对象;许多只是具有返回数组或 stdClass 对象的类似存储库的类(像这样创建的简单匿名对象:)$someObj = new stdClass
,这意味着这些系统缺乏真正的面向对象编程,但做出这样的决定通常有实际原因。
面向对象编程的真正目的比我上面提到的更深:它是关于设计系统中的对象以反映我们的心智模型(一个包括最终用户和程序员视角的联合心智模型) . 这是另一个很好的引用,这次来自发明 MVC 模式的 Trygve Reenskaug:
我认为面向过程和面向对象编程之间的区别在于面向过程回答了这个问题:“会发生什么?”。面向对象回答了一个额外的问题:“谁做的?” (来源)
最后,我建议阅读一本专门介绍 PHP 中的面向对象编程的书。一个很好的例子是 Matt Zandstra 的PHP Objects, Patterns and Practice。