静态是不好的,但是工厂模式呢?


13

我正在进行TDD项目,所以我尝试尽可能地坚持与这种开发相关的良好实践。其中之一是尽可能避免静态和全局。

我面临着这个问题:我有一个对象“文章”,可以将其链接到“选项”(附加的“微型文章”)。

我无法弄清楚如何拥有一种不会产生反效果或产生过多查询的好的方法,因为我将处于一种一切都分离的情况下,我基本上将需要对每个对象进行一次查询。

从我的实际角度来看,我看到3个选项:

1)构建内部文章:

class Article
{
    //[...]
    public function getArrOption(){
        //Build an array of Options instance.
        //return an array of Options.
    }
}

优点:直截了当

const:可维护性:article对象现在包含Option对象的构建逻辑。这可能会导致代码重复。

2)使用optionFactory

class Article
{
    //[...]
    public function getArrOption(){
        return OptionFactory::buildFromArticleId($this->getId());
    }
}

优点:构建逻辑并非超出Article类

const:我违反了“静态很难模拟”的规则,这使得我的Article类很难测试。

3)分离所有逻辑。

//Build the array of Option instance in a controller somewhere, using a Factory:
$arrOption = OptionFactory::buildFromArticleId($article->getId());

优点: Article只处理自己的责任,不关心他与选项的“父亲”链接。事情真的脱钩了

const:每次我需要访问Options时,Controller内都需要更多代码。这意味着我永远不要在对象内部使用Factory,而这对我来说似乎是个主题。

最好的方法是什么?(我错过了什么吗?)谢谢。

编辑:

更不用说如果我不能在类内部调用工厂,那么我基本上也永远不会使用惰性初始化模式...


我不确定是否相关,但是我使用PHP进行编码,因此“应用程序”的状态更少。如果未存储在会话Cookie中,则必须重新加载每个页面之间的所有数据。这意味着我们无法像应用程序语言那样预加载所有内容。
FMaz008 2011年

@job:好吧,因为在单元测试中,方法内部的静态调用几乎是无法替换的。目标是使用依赖注入。但是工厂通常是静态的,因此无法注入。
FMaz008 2011年

Answers:


12
  1. 静态不是“坏”的,它是不可模拟的。您仍然可以在没有意义的嘲笑中使用它。

  2. 那不是工厂模式,它看起来像存储库模式,尽管可能不是。在Factory中,您可以拥有多个具有相同接口/基类的类,并且您想要分离出决定返回哪个类的逻辑。存储库从其存储库中获取数据,从而抽象出该存储库的实现(本文无需了解其选项是否存储在同一数据库,另一个数据库,XML文件,CSV文件等中)。

  3. 您已经忽略了在构造函数中为Article类提供一个ObjectFactory(或Repository或其他对象)对象的可能性,该对象可以在该对象上调用buildFromArticle方法。

我的PHP生锈了,但我认为它看起来像这样:

class Article
{
    private $_option_repository;

    public function __construct($option_repository) {
        $_option_repository = $option_repository;
    }

    //[...]

    public function getArrOption(){
        return $_option_repository->buildFromArticleId($this->getId());
    }
}

我认为这可以满足您上面的所有优点。


因此,可以具有Factory / Repository / Mapper实例吗?我需要一个依赖容器或某种东西,因为如果我们需要为一个对象可以返回的所有可能的对象注入所有的factory / repository / mapper,那么很快就会产生很多。(
Article-

1
好的,这是更好的选择。我通常保留静态用法来删除重复的代码,因为重复代码的大小足以在多个类中进行测试。是的,一个IOC / DI容器将使您的生活更加轻松。使用一个。
pdr

1

这是一篇引述论文的引文,认为您永远不需要静态方法,证明抽象工厂令人困惑,并建议对依赖注入作为解决方案进行轻微的语言更改。

实例与其类之间的紧密耦合破坏了封装,并且与静态方法的全局可见性一起,使测试变得复杂。通过使依赖注入成为编程语言的一种功能,我们可以完全摆脱静态方法。我们采用以下语义更改:

(1)用对实例变量的访问来替换每次出现的全局变量;

(2)让实例变量在实例化时自动注入到对象中。

“讨论:将职责与静态方法分离,以实现细粒度的可配置性”

Wayback Machine Link


3
尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能无效。
gnat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.