PHP OOP模块化CMS对象设计

时间:2013-06-23 00:49:51

标签: php class oop object

我想就如何在模块化CMS系统中设计对象提出建议。我一直在寻找几个小时,但我找不到正确的答案。

如何设计与事物互动的类?可以说我有这些课程:

cDb() // for database interactions
cUser() // for all user actions
cSession() // for interactions with session data.
cAnotherObject // multiple another objects from future modules

我应该以某种方式扩展所有这些,所以最后,我最终会得到一个像这样的对象:

$myvar = new cLatestClass(); 

[cSession扩展cDb,cUser扩展cSession ......等等]

如果是这样,如何在模块中动态加载类?是否只使用多个var来保存对象?

$user = new cUser(); 
$session = new cSessions();
 ... etc.

我真的希望有人在这里能回答我,希望能教会我如何正确地做到这一点。

2 个答案:

答案 0 :(得分:3)

首先,我建议退后一步,了解面向对象的方方面面。创造“面向对象编程”一词的Alan Kay曾将其描述如下:

  

我认为物体就像生物细胞和/或个体   网络上的计算机,只能与消息通信。   (source)

在PHP(以及大多数面向对象语言)中,这些消息通常是方法调用,或者在公共属性的情况下,获取和设置它们的值。

因此,将系统中的对象视为一个更大的有机体中的单个细胞,协作以实现更大的目标,而不是试图将您需要的所有行为混合到一个对象中。

这是一个很大的主题,很多书都写在上面,但就你在问题中提到的对象而言,我首先会区分它们所属的不同类别。数据库或会话对象可以被视为一种“服务”,其他对象(例如,您的控制器,如果您使用的是MVC框架)将依赖于该服务。正如其他人所提到的,依赖注入是处理此类服务的一个很好的解决方案,但在大多数情况下我不建议将它用于像User类这样的东西,每个用户应该有一个实例(当然不是字面上的 - 你'只将特定用户对象加载到处理特定请求所需的内存中,在许多情况下只是当前用户的实例。)

要了解有关依赖注入的更多信息,我建议使用this article Martin Fowler创造这个术语的地方,以及他提到的一个更简单的替代方案,称为服务定位器的依赖注入容器。

(依赖注入容器方法更健壮,但也更复杂;幸运的是有good open-source library for it)。

用户,文章和类别都是CMS中域对象的示例。这些是MVC的“M”(模型)的一部分(也称为域模型)。当然,您仍然需要一种方法将这些对象放入和放出数据库,因此您可能还需要某种Repository或Query类(Repository类可以被视为服务)。并非所有PHP系统都有真正的域对象;许多只是具有类似于存储库的类,它们返回数组或stdClass对象(简单的匿名对象,如下所示:$someObj = new stdClass),这意味着这些系统缺乏真正的面向对象编程,但通常有实际的原因,做出这样的决定。

面向对象编程的真正目的比我上面提到的更深入:它是关于在系统中设计对象来反映我们的心理模型(一个包含最终用户和程序员)。这是另一个好的引用,这一次来自Trygve Reenskaug,他发明了MVC模式:

  

我想到了面向过程和对象之间的区别   面向程序设计就是面向程序的答案   问题:“会发生什么?”面向对象的答案是额外的   问题:“谁做到了?” (source

最后,我建议您阅读一本专门介绍PHP中面向对象编程的书。 Matt Zandstra是一个非常好的PHP Objects, Patterns and Practice

答案 1 :(得分:1)

  

我应该以某种方式扩展所有这些,所以最后,我最终会得到一个像这样的对象:

不,你当然不应该。扩展课程时,您应该有is-a关系。

会话不是数据库。用户肯定不是会话。您所看到的可能是dependency injection

假设您的User类需要数据库连接。这看起来像是:

class User
{
    private $dbConnection;

    public function __construct(\PDO $dbConnection)
    {
        $this->dbConnection = $dbConnection;
    }

    public function doSomethingWithDb()
    {
        $this->dbConnection->query('SELECT...');
    }
}

$dbConnection = new PDO('/* dsn string */', 'user', 'pass');
$user = new User($dbConnection);

如果你要从User类中提取数据库查询,那么你就更好了,这样你就不必使用数据库了。

另外作为CS说明:为什么要在c之前添加课程?

关于您的模块系统。这将取决于您将如何设置模块,但您可能需要查看依赖注入容器以将动态模块连接在一起。