1

我知道所有逻辑等都应该进入控制器,但我有一个 SQL 语句,其中的某些部分由另一个函数的返回值确定。

在我的模型中:

    $cols = 'products.id, name, currencies.symbol, basePrice';
    $m = new AuthController();
    if($m->moduleExists('Sales'))
    {
      $cols .= 'lastSold';
    }

或者在我的控制器中并将 SQL 作为参数传递给模型?

    $cols = 'products.id, name, currencies.symbol, basePrice';
    if($this->moduleExists('Sales'))
    {
      $cols .= 'lastSold';
    }
4

1 回答 1

1

tldr; 版本

考虑到关注点的分离和解耦,与持久性相关的代码最好不包含与特定系统的子模块相关的业务逻辑(无论该逻辑属于模型部分的控制器、MVC 的控制器还是控制器部分,或任何程序员向系统介绍的其他部分)。应避免从持久层访问业务逻辑以保持解耦,应优先考虑业务逻辑访问持久层的其他方式。

理由

在您的模型中,您应该放置与视图中显示的内容无关的代码,即模块是否存在或是否被授权拥有这样的模块。您的模型中的代码应该可供您的子系统、其他系统、任何独立于您的视图甚至与特定用例相关的业务逻辑的事物使用。它应该具有与系统范围相关的逻辑。尽管授权似乎具有系统范围,但应格外小心处理,因为它可能导致脆弱的设计。在控制器级别拥有它更加灵活。想象一下尝试支持多种授权技术。

根据授权或视图标准来修改查询不会保持稳定的独立模型。

所以是的,它应该进入你的控制器。

控制器无论是与视图相关的控制器还是特定业务逻辑(用例相关或系统相关,即授权控制器)现在都可以具有更改查询的授权标准,并且将来可能会出现与特定用例或子系统域。这意味着控制器可以更改,您甚至可以引入不同的控制器以特定方式访问同一模型。

执行

关于您的问题有很多方法。如,

  • 从您的持久层检索完整版本的数据,即所有列,并让您​​的控制器根据逻辑(即用户授权)决定要显示的内容
  • 在持久层中有多个查询,独立于其他逻辑,即 queryProducts、queryProductsWithTotals、queryProductsWithLastSoldDate,然后让您的业务逻辑控制器决定调用哪个
  • 在持久层中创建一个通用函数,接受 cols(如果可能的话,非魔法值)以便参数化可以根据其他控制器具有的逻辑查看的内容并相应地调用此函数
  • 一般来说,最好避免将sql查询放在不同的地方,因为维护变得困难。然而,在某些情况下,这种情况可能会发生,并且很大程度上取决于系统的设计,即业务控制器具有每个用例的自定义查询,调用持久层以便执行。
于 2013-10-20T13:35:11.180 回答