Php 关注点分离;MVC;为什么?

Php 关注点分离;MVC;为什么?,php,model-view-controller,user-interface,oop,Php,Model View Controller,User Interface,Oop,在我开始下一个主要项目之前,我正在阅读OO。我是一名PHP开发人员,致力于web应用程序的开发 我特别感兴趣的一个领域是用户界面;特别是如何构建它并将其连接到我的OO“模型” 我一直在读这方面的书。我最喜欢的是: “所有对象都必须提供自己的UI” 考虑到我的问题,我可以看到这很有效。例如,我构建“用户”对象来表示登录到我的网站的人。我的方法之一就是“展示你自己”或类似的方法。我可以在我的代码中使用它。也许从这个开始,他们的名字就是这样。稍后,如果我需要调整以显示他们的名字+小化身,我可以只更新

在我开始下一个主要项目之前,我正在阅读OO。我是一名PHP开发人员,致力于web应用程序的开发

我特别感兴趣的一个领域是用户界面;特别是如何构建它并将其连接到我的OO“模型”

我一直在读这方面的书。我最喜欢的是:

“所有对象都必须提供自己的UI”

考虑到我的问题,我可以看到这很有效。例如,我构建“用户”对象来表示登录到我的网站的人。我的方法之一就是“展示你自己”或类似的方法。我可以在我的代码中使用它。也许从这个开始,他们的名字就是这样。稍后,如果我需要调整以显示他们的名字+小化身,我可以只更新这一个方法,嘿,普雷斯托,我的应用程序被更新了。或者,如果我需要将他们的名字链接到他们的个人资料,嘿,普雷斯托,我可以很容易地从一个地方再次更新

在面向对象系统方面;我认为这种方法很有效。查看其他StackOverflow线程,我在“关注点分离”下发现了以下内容:

在计算机科学中,分离 关注点(SoC)是 将计算机程序分解为 相互重叠的明显特征 尽可能少地使用功能 关注是指任何利益或利益 专注于一个项目。通常, 关注点是功能的同义词 或行为。SoC的进展是 传统上通过 模块化和封装,具有 信息隐藏的帮助。”

在我看来,我已经做到了这一点。我的用户对象隐藏了它的所有信息。我的代码中没有任何地方在显示之前说$user->get\u user\u name()

然而,这似乎与其他人认为的“最佳实践”背道而驰

引用同一问题的“选定”(绿色)答案:

“关注点的分离正在保持 每个关注点的代码 分离。更改接口 不应要求更改 业务逻辑代码,反之亦然。 模型-视图控制器(MVC)设计 模式是一个很好的示例 为了更好地解决这些问题 软件可维护性。”

为什么这有助于提高软件的可维护性?当然,有了MVC,我的观点必须对模型了解很多?有关这一点的详细讨论,请阅读JavaWorld文章:

无论如何。。。终于说到了真正的问题

1.有人能推荐任何详细讨论这一点的书吗?我不想要一本MVC的书;我不相信MVC。我想要一本讨论OO/UI、潜在问题、潜在解决方案等的书。。(可能包括MVC) 亚瑟·瑞尔的

涉及到它(也是一本很好的书!),但我想要更详细的东西

2.有谁能提出一个和Allen Holub的JavaWorld文章解释MVC为什么是个好主意一样好的论点吗

非常感谢任何能帮助我得出结论的人。

  • 考虑一下所需要的代码量 如果你愿意的话,我会上那门课 您想公开相同的信息,而不是 仅作为UI上的Html,但作为一部分 一个RSS、一个JSON、一个rest服务 使用XML,[插入其他内容]
  • 这是一个漏洞百出的抽象概念,意味着它试图给你一种感觉,那就是它将是唯一知道这些数据的部分,但这不可能完全是事实。假设您希望提供一个与多个外部第三方集成的服务。你将很难强迫他们使用你的特定语言来与你的服务集成(因为它是唯一一个可以访问它正在使用的数据的类),或者如果在另一方面你暴露了它的一些数据,你就不会对那些第三方系统隐藏数据
更新1:我对整篇文章作了全面的介绍,作为一篇老文章(99),它并不是我们今天所知道的MVC与面向对象的关系,也没有反对SRP的论点

你可以完全按照他所说的去处理上面我提到的场景,具体的类负责将对象的公共契约转换为不同的格式:主要的问题是我们没有一个明确的地方来处理这些更改,而且我们不希望信息被重复。因此,在html的情况下,您完全可以拥有一个呈现信息的控件,或者一个将其转换为html或[insert reuse mecanism here]的类

顺便说一句,我有一个闪回与RMI位。无论如何,在那个例子中,你可以看到他与一种沟通的麦加主义联系在一起。也就是说,每个方法调用都是远程处理的。我想他也很关心开发人员的代码,他们没有得到一个对象并对返回的信息进行操作,而是通过大量的小Get调用来获取大量不同的信息


另外,我建议您阅读有关DDD和Solid的信息,正如我在SRP中所说的,我不会说这是作者抱怨的类型。所有对象都知道如何显示自己的想法的问题在于每个对象只能以一种方式显示。如果要提供用户的详细视图和摘要视图,会发生什么。如果要显示合并多个对象(例如用户及其关联地址)的视图,会发生什么情况。如果您将业务对象(用户)与知道如何显示它们的内容分离,那么您就没有更多的代码要编写,您只需将其分离到不同的位置

这使得软件更易于维护,因为如果用户对象行为不正确,您就知道它是用户,如果显示不正确,您就知道它是视图。在需要为应用程序提供新接口的情况下(例如,您决定提供
 public class User
 {
    public string FirstName;
    public string LastName;
 }
posts
id date_created title body hits
$sql = "SELECT * FROM posts ORDER BY hits DESC LIMIT 5";
$result = mysql_query($sql);

while ($row = mysql_fetch_assoc($result)) {
    echo "<a href="post.php?id=$row['id']">$row['title']</a><br />";
}
post_model.php

class post_model {
    public function get_popular($number) {
        $sql = "SELECT * FROM posts ORDER BY hits DESC LIMIT $number";
        $result = mysql_query($sql);
        while($row = mysql_fetch_assoc($result)) {
            $array[] = $row;
        }
        return $array;
    } 
}
home_controller.php

class home_controller {
    $post_model = new post_model();
    $popular_posts = $post_model->get_popular(10);

    // This is the smarty syntax for assigning data and displaying
    // a template. The important concept is that we are handing over the 
    // array of popular posts to a template file which will use them 
    // to generate an html page
    $smarty->assign('posts', $popular_posts);
    $smarty->view('homepage.tpl');
}
homepage.tpl   

{include file="header.tpl"}

 // This loops through the posts we assigned in the controller
 {foreach from='posts' item='post'} 
    <a href="post.php?id={$post.id}">{$post.title}</a>
 {/foreach}

{include file="footer.tpl"}
subpage_controller.php

class subpage_controller {
    $post_model = new post_model();
    $popular_posts = $post_model->get_popular(5);

    $smarty->assign('posts', $popular_posts);
    $smarty->view('subpage.tpl');
}
subpage.tpl

{include file="header.tpl"}

<div id="sidebar">

 {foreach from='posts' item='post'}
    <a href="post.php?id={$post.id}">{$post.title}</a>
 {/foreach}

</div>

{include file="footer.tpl"}
{include file="header.tpl"}

 {foreach from='posts' item='post'}
    {if $post.date_created == $smarty.now}
        <a class="new-post" href="post.php?id={$post.id}">{$post.title}</a>
    {else}
        <a href="post.php?id={$post.id}">{$post.title}</a>
    {/if}
 {/foreach}

{include file="footer.tpl"}
post_model.php

class post_model {
    public function get_popular($number) {
        $sql = "SELECT * , COUNT(comments.id) as comment_count
                FROM posts 
                INNER JOIN comments ON comments.post_id = posts.id
                ORDER BY comment_count DESC 
                LIMIT $number";
        $result = mysql_query($sql);
        while($row = mysql_fetch_assoc($result)) {
            $array[] = $row;
        }
        return $array;
    } 
}