PHP OO设计:扩展静态类或实例类?

时间:2012-11-03 07:47:36

标签: php oop inheritance static

我有一个应用程序,它定义了对常见对象类型的某些操作。

例如,您可以拥有论坛帖子和图片。对于每个论坛帖子和图片,您可以执行以下操作:推荐,评论,评分。

我目前定义了一个静态类

class CoreObjectUtil
{
    protected static $_objObjKey  = null;
    protected static $_objTypeKey = null;

    public static function getComments (...) {...}
    public static function getCommentsArray (...) {...}
    public static function getRatings (...) {...}
    public static function getRatingsArray (...) {...}
}

然后按照这个

进行子类化
class ForumPostUtil extends CoreObjectUtil
{
    protected static $_objObjKey  = 'forumpost';
    protected static $_objTypeKey = 'FP';
}

为论坛帖子提供相关功能。这两个参数足以让CoreObjectUtil中的通用代码知道如何为这些函数适用的每个对象类型做些什么。

要使用这些函数,我在我的实例类中调用selectPostProcess()类,如下所示:

public function selectPostProcess ($data)
{
    $data = ForumPostUtil::mergeRatings ($data);
    $data = ForumPostUtil::mergeComments ($data);
    ...
}

这很好用,并且主代码集中在CoreObjectUtil类中,其子类提供数据设置,让CoreObjectUtil中的代码知道该怎么做。

另一种方法是将代码从CoreObjectUtil移动到基本实例类中,然后在我的实例类中继承。因此,不是从CoreObjectUtil调用静态方法,而是使用$ this-> getComments()等方法调用。

从功能类型的角度来看,这两种方法都可以正常工作。我想知道ObjectOriented设计指南和经验丰富的ObjectOriented开发人员对这两种方法的看法。这样做的方式更可取,为什么?

我很感激对此事的任何想法/见解。我可以毫无问题地编码,但是我很难决定采用哪条路线。

1 个答案:

答案 0 :(得分:0)

我认为,你现在拥有的代码是OOP中最具程序性的方法,即你现在拥有的是OOP的另一面。使用class关键字并不能使其成为OOP。

首先,你应该忘记静电,不是它不好用,但它很容易被滥用,如果功能可以属于你真的必须先尝试建模域概念的对象(在您的案例中与论坛相关)。只有当这种方式没有意义时,你才能在实用程序类的某个地方将它作为静态方法。

说实话,你必须围绕OOP心态重新设计你的应用程序,即定义具有模拟特定概念或过程的行为的类,并且只有一个责任。除此之外,您不应该将业务对象(构建论坛概念的对象)与持久性问题混合在一起,即不要将相同的对象业务功能和数据库访问放在一起。使用单独的类来访问存储。

使用Repository模式将业务层与持久层分开。尽量不要将创建/更新功能与查询混合在一起,如果它使事情变得复杂。在这种情况下,请使用专门用于查询的单独读取模型。

您向我们展示的代码是关于查询的。你可以拥有一个简单的DAO / Repository(在这种情况下称之为你想要的),就像这样

 class ThreadViewData
 {
    public $Id ;
    public $Title;
    public $Comments; //etc
 }

  class ThreadsQueryRepository
  {
      //we inject the db access object , this helps with testing
      function _construct($db) { } 
       public function GetThread($id){ } //this returns a ThreadViewData
  }

postPRocess功能是一种可以合并评级和评论的服务。但也许合并功能更适合评级和评论对象。我不知道域名实际上是否提供了有效的建议。

重点是,你必须考虑不在函数中的对象,现在你所拥有的只是函数。