【问题标题】:OOP, MVC - Models and ObjectsOOP,MVC - 模型和对象
【发布时间】:2011-01-27 22:23:38
【问题描述】:

我正在使用 CodeIgniter 构建一个站点,并且我有一个名为 Blog_model 的模型。

Blog_model 中,有一些方法可以拉取特定主题的帖子列表,例如getPopularPosts()

getPopularPosts() 查询posts 表以获取topic_id 与指定的匹配的帖子列表,并按受欢迎程度对其进行排序。因此,这是对整个帖子表的查询(假设最终这将非常大)以查找所有带有 topic_id x 的帖子。

然后,foreach 结果 as 一个单独的帖子 ID,它创建一个新的 Post 对象。 Post 类通过设置字段id 来构造一个帖子。

为了返回Post 的内容,我指定$post->getPost();,它再次查询posts 表以返回给定id 的整行。

这个组织(AFAIK)遵循一个很好的面向对象原则。但是现在,对于每个帖子(再次,假设有数千、数百万,等等),我必须首先查询ids 的列表,然后再次获取每个帖子的内容。如果我返回 30 个帖子,这意味着 31 个单独的查询。

或者,我可以打破面向对象的模式并为posts 中的每个帖子拉*,其中topic_id = x。然后,我有一个查询返回所有 30 个帖子,但现在我感觉不是那么面向对象。

怎么办?

【问题讨论】:

  • 你觉得“感觉如此面向对象”很重要吗? - 如果您担心性能或其他问题,您可以在后端运行它作为完整的 oo 更改并将结果写入纯文本文件。然后您甚至不需要为每个帖子运行查询,您只需使用初始查询中的 id 即可显示缓存文件中的结果。但是,如果您正在寻找选择您提到的选项之一的评论,我会使用联合查询。如果我没记错的话,代码点火器并不是严格意义上的oo。我认为是 Kohana,他们有 ORM 来做你想做的事。
  • 如果它有所作为,那就是 CodeIgniter 2。
  • 您的问题中有很多信息,如果您希望在此处正确解决这些问题,请给出您所讨论内容的代码具体示例。

标签: database oop model-view-controller design-patterns codeigniter


【解决方案1】:

没有理由有这么多的查询。您基本上只是在寻找来自特定主题 ID 的 X 个帖子...您应该将其作为一个对象返回,然后在 PHP 中遍历结果,因为一旦您到达,这样做会明显更快拥有数百万行的意义

你应该这样做:

class blog_model extends CI_Model {

     function __construct(){
         parent::__construct();
     }

     function getPopularPosts($cat_id){
        /* Using method chaining here since you sound like you
           really want to utilize everything OO CI has to offer */
        $posts = $this->db->select('id, title, post_info')
                  ->where('topic_id', $topic_id)
                  ->get('posts');

        if($posts->num_rows() > 0){
             return $posts;
        }else{
             return FALSE;
        }
     }    
}

那么您的控制器将如下所示:

class blog extends CI_Controller {

     function __construct() {
         parent::__construct();
     }

     function blog_posts($popular_post_id) {
         $this->load->model('blog_model');
         $posts = $this->blog_model->getPopularPosts($popular_post_id);

         if(!empty($posts){
             foreach($posts as $post){
                 echo $post->id;
                 echo $post->title;
                 echo $post->post_info;
             }
         }else{
             echo 'There are no posts';
         }

     }

 }

以您当前设置的方式生成大量查询没有任何好处(实际上是一个大问题),而不是从查询中生成一个对象并遍历控制器中的每一行并执行数据随心所欲。

【讨论】:

  • 但是本着 OOP 的精神(也许这意味着只见树木不见森林),将这样的逻辑放在 Post 类中不是更“正确”吗?因为也许我想获得特定帖子的回复。使用您的方法,这会将getPost()getReplies() 放在同一类下;而在我看来,getReplies() 应该是 Post 类的方法。
  • 是的,我认为您完全不了解 OOP 的实际含义以及如何实现它...如果您要获得单个条目的回复,那应该是一个不同的功能在 blog_posts 模型中,并且只查询特定的博客帖子 id...如果您将获得多个帖子的多个回复,那么您将寻求做一些 mysql JOIN。一个简单的说法是,您的目标应该是使用尽可能少的查询来完成您需要的事情。 OOP 只是一种让您保持井井有条的做事方式。
  • 值得一提的是,我最初按照您描述的方式进行了设置。根据您的回答,我已恢复到此设置。代码的整体重量与 PostReply 类的重量非常相似,即使事情没有我想要的那样有条理,它仍然非常干燥。此外,我可以运行单个查询来代替 (_number-of-posts_) + 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
  • 2011-12-07
  • 1970-01-01
  • 2019-07-10
  • 2015-03-28
  • 2013-07-26
相关资源
最近更新 更多