草庐IT

php - 模型类应该代表一个实体还是返回它

coder 2023-12-31 原文

我正在使用 CodeIgniter 设计网络应用程序(但我认为这个问题通常适用于 Web 应用程序中的 MVC 模式)。

当我为某个数据库实体(例如,BlogEntry)设计模型类时,我基本上有两种选择:

“经典 OOP”方法是让类代表 实体,即类的一个实例 BlogEntry。在 CodeIgniter 中,这将导致类似的代码

class Blogentry extends CI_Model {
    function load($id) {
      // Access database
      $this->id = $dbresult.id;
      $this->title = $dbresult.title;
      $this->author = $dbresult.author;
    }
}

要访问某些博客条目,我会执行 $this->load->model('blogentry');,调用 $this->blogentry->load( $id) 然后使用模型类实例。

我在野外经常看到的另一种方法是让模型返回某种数据结构中的实体。在代码中:

class Blogentry extends CI_Model {
  function get_entry($id) {
    // Access database, yielding $dbresult
    return $dbresult;
}

有了这个我会写

$this->load->model('blogentry');
$the_entry = $this->blogentry->get_entry($id);

在 Controller 中并使用 $the_entry。在第二种情况下,该类更像是一个 factory。或 builder类。

这两种方法中的任何一种都被认为是在 MVC 中执行 M 的“正确方法”吗?我想,我经常看到第二种方法,但我没有看到那么多 MVC-Webapps。关于为什么第一种或第二种方法可能更合适的想法?

最佳答案

首先,CodeIgniter 不是 MVC 框架。最适合的范例可能是 MVP 或类似 ORM-Template-Adapter 的东西。因此,让我根据命名谬误分解我的答案:

在经典/传统 MVC(不是框架声称的 MVC)中,模型不是类或单个文件,而是包含所有领域业务逻辑的,通常仅由 Domain Objects 之类的东西组成, Data Mappers ,以及处理调用实体和域逻辑之间的接口(interface)的东西,以将此类代码保留在 Controller 之外(例如,在 MVC 中)。 Tereško names them "services" ,这足以作为一个准官方名称。

因此在传统的 MVC 中,对模型层的请求通过“服务”传入,而“服务”又与领域对象和数据映射器交互。

显然,所有这些与 CodeIgniter 和其他框架所谓的“MVC”几乎没有关系。在这种设计模式(我简称为“CIMVC”)中,Model是Controller调用和操作的类,直接与数据库交互。在模型中的成员变量中存储数据并没有太多的语义意义,但如果您对类似的东西感兴趣,请查看任何用 CIMVC 编写的 ORM 插件/库。 (尽管 ORM 解决方案在符合传统 MVC 方面不会更好...)

至于常见的做法,我见过的大多数 CI 应用程序都会将“原始”数据库数据返回给 Controller 进行处理;这将域业务逻辑保留在模型中。在 CIMVC 中,我个人的偏好是最小化/消除模型中除域业务逻辑之外的任何内容。

tl;dr - CodeIgniter 中的“传统/正确”MVC 基本上是不可能的,因此试图强制您的 CI 代码符合传统 MVC 范例是愚蠢的(并且可能会让您精神错乱)

编辑:为了澄清之前关于模型层中业务逻辑的一些混淆,是的,您应该在模型层中拥有所有业务逻辑。但是,如果正在进行额外的数据处理(排序、操作等),现在我们将进入违反 DRY 和 SRP 的危险区域;您希望模型可重用,因此请注意不要添加过多或此类专用逻辑,以免它在应用程序的其他部分变得无法使用。

关于php - 模型类应该代表一个实体还是返回它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11832921/

有关php - 模型类应该代表一个实体还是返回它的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  6. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  7. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  8. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  9. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐