Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP OO设计:扩展静态类还是实例类?_Php_Oop_Inheritance_Static - Fatal编程技术网

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

PHP OO设计:扩展静态类还是实例类?,php,oop,inheritance,static,Php,Oop,Inheritance,Static,我有一个应用程序,它定义了常见对象类型的某些操作 例如,你可以有论坛帖子和图片。对于每个论坛帖子和图片,您可以执行以下操作:推荐、评论、评分 我目前已经定义了一个静态类 class CoreObjectUtil { protected static $_objObjKey = null; protected static $_objTypeKey = null; public static function getComments (...) {...} pu

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

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

我目前已经定义了一个静态类

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';
}
 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
  }
为论坛帖子提供相关功能。这两个参数足以让CoreObjectUtil中的通用代码知道如何处理这些函数适用的每个对象类型

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

public function selectPostProcess ($data)
{
    $data = ForumPostUtil::mergeRatings ($data);
    $data = ForumPostUtil::mergeComments ($data);
    ...
}
这可以很好地工作,并使主代码集中在CoreObjectUtil类中,其子类提供数据设置,让CoreObjectUtil中的代码知道该做什么

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

从功能类型的角度来看,这两种方法都可以很好地工作。然而,我想知道面向对象的设计准则和有经验的面向对象开发人员对这两种方法有何看法。哪种方法更可取?为什么


如果您对此事有任何想法/见解,我将不胜感激。无论哪种方式,我都可以毫无问题地编写代码,但我很难决定采用哪种方式。

我认为,您现在的代码是有史以来最程序化的面向对象方法,也就是说,您现在拥有的是面向对象的对立面。使用class关键字并不能使其成为OOP

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

老实说,你必须围绕面向对象的思维方式重新设计你的应用程序,也就是说,用行为定义类,这些行为模拟特定的概念或过程,并且只有一个职责。此外,您不应该将业务对象(为论坛概念建模的对象)之类的东西与持久性问题混为一谈,即不要将业务功能和数据库访问放在同一个对象中。使用单独的类访问存储

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

您向我们展示的代码是关于查询的。您可以有这样一个简单的DAO/存储库(在本例中可以随意称呼它

class ForumPostUtil extends CoreObjectUtil
{
    protected static $_objObjKey  = 'forumpost';
    protected static $_objTypeKey = 'FP';
}
 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
  }
后处理功能是一种可以合并评级和评论的服务。但是合并功能可能更适合评级和注释对象。我不知道该领域是否真的给出了一个有效的建议


关键是,你必须在对象而不是函数中思考,现在你所拥有的只是函数。

谢谢你的详细回答!我将根据您提供的想法重新设计。一般的说法是:使用对象,而不是静态类函数。对象更加灵活。当您创建所有静态类时,它甚至不是OOP。“类”实际上就像变量和函数的名称空间。基本上,这只是程序编程的另一种形式。