这个代码疯了吗?

2022-08-30 17:09:09

我正在学习一个教程,我认为这是由一个不知道自己在做什么的人编写的(已经发现了2个明显的错误,其余的代码很混乱)。但我不想完全诋毁这个人,所以我在这里问一些我不明白的事情。

首先,我将发送100个布朗尼点,我的2只宠物和一盒巧克力给任何可以向我解释此代码发生了什么的人。

他使用的是基于模块的架构。模块名称为 。模块具有 MVC。模块有自己的内部。frontmodulelibrary

  /modules/    
      /frontmodule/
          /models/
          /views/
          /controllers/        -- the /module controller is here (undestandable)
          /library/            
             /Controller/      -- the /module/library controller is here (why?!)
                /Action/

首先是令人困惑的部分。为什么每个模块都有一个内部库,以及为什么该内部库有自己的 和 。这是最佳实践吗?我认为这个库可以移动到模块可以使用的插件中。不确定。。controllersactions

现在是有趣的部分....除了每个模块都有自己的内部库之外,还有一个由所有模块共享的Common库(请参阅下面的同一文件夹级别),并且Common库也有自己的控制器和操作(就像每个内部库都有自己的控制器和操作一样)/modules

  /modules
  /library/
      /Common/
          /Controller/         -- the /common/library controller is here (why?!)
              /Action/
                  /Helper/
              /Plugin/

所以我们有 3 个控制器:

  • 模块控制器
  • 模块内部库的控制器
  • 公共库的控制器

现在,我认为这是使生活过于复杂的疯狂部分

他说:模块控制器扩展了模块的库父控制器,这也扩展了公共库控制器。

class IndexController 
       extends Frontoffice_Library_Controller_Action_Abstract { ... }

abstract class Frontoffice_Library_Controller_Action_Abstract 
       extends Custom_Controller_Action_Abstract { ... }

所以我猜:

  • 模块控制器 = 索引控制器
  • 模块内部库的控制器 = Frontoffice_Library_Controller_Action_Abstract
  • 公共库的控制器 = Custom_Controller_Action_Abstract

其中扩展module controllermodule internal library's controller

并扩展module internal library's controllercommon library's controller

以前有人见过这样的东西吗?我的猜测是,这段代码并不容易维护,但也许那些对zend更有经验的人可以告诉我这个家伙想要实现的目标。应用程序结构有点太乱了。我认为他正在滥用MVC,而不是使用它来简化应用程序及其可维护性。


答案 1

Zend Framework的伟大之处在于它是随意使用的,这意味着您可以使用单个组件,也可以全部使用它们。大多数组件通过配置或扩展(继承或组合,采埃孚更喜欢后者)也非常灵活。

Zend Framework MVC 非常灵活...甚至到了许多人指责它被过度设计或臃肿的地步。这是主观的。

当然,您可能不想使用Zend框架来制作简单的联系表单;但是,没有什么可以阻止您只使用Zend_Mail,而没有Zend MVC / Application Zend_Form。考虑到灵活性,目前没有一种方法被吹捧为将应用程序组织成模块的最佳方法。这是一项最好留给实施者的任务。

这就把我们带到了手头的教程。教程作者提出了一种重用策略。这是一件好事。但是,他的方法存在一些缺陷。

  1. 每个模块一个库。这并不一定是坏事。但是,在大多数情况下,这不是必需的。让我们探讨一下我们有哪些选择,以防万一由于某种原因需要这样的结构。

    a. 构建一个通用库(您很可能已经这样做了)命名空间(如果< 5.3 则为伪,如果>= 5.3,则为实际命名空间)。

    b. 利用固有的“资源自动加载器”http://framework.zend.com/manual/en/zend.loader.autoloader-resource.html

    注意:我个人没有使用过资源自动加载。有一次我确实使用了它,我发现我可以把这些项目移到我的图书馆。话虽如此,这是有用的。当您期望跨项目或分发混合和匹配模块时,它似乎会大放异彩。恕我直言,ZF2将以一种不那么棘手的方式解决这个问题。

  2. 可重复使用的基本控制器。同样,重用是伟大的;但是,Zend Framework为子类(继承)控制器提供了更好的替代方案。首先,以下是不使用控制器继承的一些原因:

    a. 当您有多个模块差异到每个模块需要一个基类,但功能在每个模块的基控制器类之间复制/粘贴时,保持干燥是失败的。

    b. 管理继承的属性变得很困难,因为很难可视化每个控制器/操作正在使用哪些继承的功能

    c. PHP 只允许单个类的继承,你在这里就吹了一次继承的机会 -- 只有在没有其他选择的情况下才使用它

    替代方案

    a. 前端控制器插件 当功能/逻辑需要在每个请求上运行而不考虑模块/控制器/操作时,使用这些插件

    b. 动作助手 正如采埃孚项目负责人所提到的,“它们是 Zend Framework 中的内置机制,允许您以使用组合而不是继承的方式扩展动作控制器。在控制器中,您无法通过操作帮助程序执行任何操作。当功能需要基于每个控制器和/或操作发生时,请使用这些功能。

那么,教程中的示例是否过度设计?不一定;但是,它肯定是错误设计的候选者,因为它与Zend Framework给出的最佳实践和规定有关。

我需要离题片刻,讨论一下过度设计和臃肿的术语。

当有人告诉你某件事被过度设计和/或臃肿而没有说明上下文时,请带着一粒盐。

维基百科文章 - http://en.wikipedia.org/wiki/Overengineering 部分内容为“...当产品比其应用所需的更强大或更复杂时......“。

因此,当提到过度设计/臃肿的东西时,应该小心地限定手头的上下文应用程序。一揽子声明应该谨慎对待,在大多数情况下,根本不应该采取。这类似于说“我永远不会使用'圆锯'进行木工,因为它有太多的功能,这些功能让我感到困惑”。当然,这个工具对于小型家庭/侧面项目来说可能是过度杀戮;但是,由于它非常灵活,因此当您发现自己处于从未想过会发现自己的情况时,您会很高兴拥有此工具。

是的,大多数Web框架对于简单的CRUD应用程序(例如联系页面甚至简单的博客应用程序)都是过度杀戮的。不幸的是,大多数Web框架使用博客示例作为他们的介绍性示例 - 去图。

额外信息

  1. 如果要根据模块/控制器/操作切换布局,可以编写前端控制器插件。只需调用“Zend_Layout::startMvc”,然后为其传递布局名称和路径即可。

  2. 基于 Accept 标头(或 URL 参数或 X-HTTP-METHOD-OVERRIDE 标头)切换实际视图脚本可以使用上下文切换操作帮助程序(Zend Framework 固有的)来完成 - http://framework.zend.com/manual/en/zend.controller.actionhelpers.html

  3. 可以随意将模型实例传递给操作帮助程序。您还可以使用引导程序中的配置来配置操作帮助程序。这样,就没有必要将东西存储在全局注册表中,全局注册表只是一个美化的全局变量。这是一个隐藏的依赖项,您不需要它。为了获得最佳重用效果,您可以通过扩展Zend_Application_Resource_ResourceAbstract来创建自己的自定义插件资源 - http://framework.zend.com/manual/en/zend.application.core-functionality.html#zend.application.core-functionality.resource-resourceabstract


答案 2

这太疯狂了。你正在制作网页,对吧?这并不难。我想说的是,你发布的东西正是过度工程的定义:

http://en.wikipedia.org/wiki/Overengineering


推荐