【问题标题】:My models all tend to look the same我的模型看起来都一样
【发布时间】:2012-01-11 14:00:37
【问题描述】:

我注意到我所有的模型看起来都非常相似。它们中的大多数倾向于遵循一种模式,即它们是包含活动记录代码的方法的集合,这些代码只是彼此之间的微小变化。这是一个例子:

class Site extends CI_Model {

    public function get_site_by_id($id)
    {
        // Active record code to get site by id
    }

    public function get_sites_by_user_id($user_id)
    {
        // ...
    }

    // ...

    public function get_site_by_user_id_and_url_string($user_id, $url_string)
    {
        // ...
    }

    // Non active record methods and business logic
    // ...

}

这种方法对我来说效果很好,但我想知道是否有更优雅的解决方案。每次我需要以新的方式查找数据时,我都必须创建一个新的方法,这对我来说似乎是不对的。这是常见的做法还是我错过了重构它的方法?

【问题讨论】:

  • 这主要是使用一组active record 代替完全实现的模式层的副作用。您可能会发现 this 与重构选项相关。

标签: php oop codeigniter refactoring


【解决方案1】:

严格按照您的要求,您可以在主模型类 (CI_Model) 和您的类 (Site) 之间添加一个中间类,例如

class MyCommonMethodsClass extends CI_Model {
}

你可以在你的类(站点)中扩展它,同时把通用代码放在上面。那会起作用,并且可能会以某种方式“优雅”。事实上,最后你最终会添加你的基本的crud,站点适应的操作,到它。

现在,如果那是“干净”,那就是另一回事了。同样,严格来说,模型就是这样做的。它照顾普通和“高级”的吸气剂。是的,他们几乎总是倾向于在您的网站上使用相同的代码。问题是,尽管在您的代码中看起来不错(更少的代码),但您在技术上牺牲了业务逻辑和数据库之间的抽象。你是模型纯粹主义者还是实用主义者?

【讨论】:

  • “纯粹”与“实用”+1 - 很多时候,人们为自己做更多的工作试图以“正确”的方式做事。
  • 是的,没错,让我们把一个应用程序放在一起,等待问题来敲门。
【解决方案2】:

我认为这是见仁见智的问题,但我认为最佳实践是创建某种创建、检索、更新、删除 (CRUD) 模型,该模型执行许多基本 SQL 函数,如 GetID、UpdateByID、GetById 等。

CRUD 模型只能帮助您进行更模块化的查询。但是调用一个名为 GetId 的函数并向其传递一些参数而不是为每个表设置不同的函数是有意义的。

正如我所说,CRUD 只能做到这一点。例如,有一个函数来查询数据库用户表以检查用户是否已验证并且用户名和密码匹配是有意义的。由于这是一个独特的而不是抽象的函数,它应该有自己的函数定义。

此外,作为最佳实践,逻辑和数据库访问不应混合在同一个文件中。

【讨论】:

    【解决方案3】:

    通常的做法是使用不同的方法来处理这样的数据。 Single Responsibility Principal 声明每个对象应该只做一件事,通过使用多种方法获取非常具体的数据,您正在创建非常可维护且易于调试的代码。

    【讨论】:

    • 可能适用于倾向于做特定事情的函数,但不适用于可以应用于许多不同情况的非常抽象的函数。
    • 我还认为您误解了“单一职责”的含义,这意味着该功能具有一个动作,例如激活数据库连接的单例,但仍可以重复使用。 “单一职责”是OOP中封装的一部分,封装是代码可重用的原则。
    • 模型被认为是非常具体的,这就是模型的重点,模型的“单一职责”是对领域的特定检查,在模型中你有方法可以做具体任务。如果你有多个模型都做同样的事情,那么你可能有代码异味,然后你将公共代码移动到一个新类,然后用公共类扩展你的模型。
    【解决方案4】:

    如果您有多个提供基本相同功能的类,那么这表明您的类层次结构可能存在问题(所谓的“代码异味”)。如果它们有相似的相互作用,那么这表明它们在某种程度上是相关的。如果是这种情况,那么它们很可能都继承自一个公共超类,该超类实现了所有子类共有的功能,每个子类只是专门化了超类的通用功能。

    这种方法的优点是:

    • 您没有重复工作(SPOT、DRY)
    • 与类交互的代码可以用更通用的方式编写,并且可以处理从超类继承的任何对象(替换)

    【讨论】:

      【解决方案5】:

      我认为创建一个“基础”模型类来扩展其他模型没有任何问题。如果它坚固且经过良好测试,它可以让您的生活更轻松。一遍又一遍地创建相同的 CRUD 函数有什么意义?

      这样做的另一个好处是您可以拥有一个基础开发存储库,您可以克隆它来启动所有新项目。

      如果您需要有关如何执行此操作的示例,请查看我之前询问过的 question

      您也可以对 controllers 执行相同操作。

      【讨论】:

        猜你喜欢
        • 2021-12-04
        • 1970-01-01
        • 2012-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-14
        相关资源
        最近更新 更多