【问题标题】:Proper DocBlock comment for the method of a class, which implements Factory design pattern为实现工厂设计模式的类的方法提供适当的 DocBlock 注释
【发布时间】:2013-03-14 21:33:58
【问题描述】:

我所说的正确的 DocBlock 评论是指这样的评论:

这是课程本身:

class Factory_DomainObjects
{
    /**
     * Build domain object
     *
     * @param $name
     *
     * @return M_UserObject|M_TransactionObject
     */
    public function build($name)
    {
        $class = 'M_' . $name . 'Object';
        return new $class();
    }
}

它根据$name 参数从Core_Object 层次结构中返回一个对象。

目前Core_Object 层次结构如下所示:

我提供了带有M_UserObject|M_TransactionObject 类型描述的@return 标签。为 PHPStorm 提供自动竞争功能,符合 PHPdoc 标准。

- 但这正是你想要的,有什么问题?
- 是也不是,继续阅读 :)

问题
如果Core_Object 层次结构会发展到这样的程度怎么办?

这会使@return标签描述变得一团糟:

/**
 * @return M_TransactionObject|M_UserObject|M_Foo|M_Foo1|M_Foo2|M_Foo3|M_Bar|M_Bar1|M_Bar2|M_Bar3
 */

目前我发现的唯一解决方法:对每个对象使用单独的build 方法,即

/**
 * Build user domain object
 * 
 * @return M_UserObject
 */
public function buildUser()
{
    return new M_UserObject();
}

/**
 * Build transaction domain object
 * 
 * @return M_TransactionObject
 */
public function buildTransaction()
{
    return new M_TransactionObject();
}

您认为我的解决方法存在哪些缺陷?你会建议什么?

【问题讨论】:

    标签: php oop autocomplete phpstorm phpdoc


    【解决方案1】:

    这里的简单答案是您不应该从单个方法返回多个对象类型。让我详细说明:

    当我说“类型”时,我的意思是对象并不都以某种方式共享相同的类型信息。在您的情况下,它们都是CoreObject(顺便说一句,这是一个可怕的名称)。所以我会简单地将返回类型提示标记为CoreObject 并完成它。

    处理此类事情的首选方法是使用接口,并让您的方法返回该接口的实现。如果您没有针对所有返回类型的通用接口,那么您需要实现不同的方法(至少,或者可能是不同的工厂)。

    【讨论】:

    • Core_Object 名字是我懒惰的结果,应该是Core_DomainObjectCore_object type-hint 不会提供 IDE 自动完成功能。界面似乎是完美的解决方法!谢谢!
    • 迂腐提示:接口永远不应该是解决方法。这是一份合同。这并不是要输入提示,而是要指定行为和交互。
    • 这个迂腐的笔记真的值得一提。它引导我了解依赖倒置原则。谢谢。
    【解决方案2】:

    目前不可能。

    观看此票以了解何时实施:http://youtrack.jetbrains.com/issue/WI-6027

    如果您不想为每个类使用单独的方法,那么我可能只建议将 PHPDoc @var cmets 用于局部变量(这可能非常不方便 - 取决于您的使用方式它):

    /** @var M_FooObject $myFoo */
    $myFoo = $factory->build('Foo');
    

    【讨论】:

    • 感谢票证参考。至于解决方法,它使文档无法提供信息(@return mixed/object@return M_UserObject)。顺便说一句,@vardeprecated。考虑改用@type
    • “顺便说一句,@var 已被弃用。考虑改用@type——当然——只要 IDE 真正支持它。跨度>
    • "@var is deprecated" 是一个笑话。他们该 github 页面的维护者应该“修复”它,这是一厢情愿的想法,与如何使用 docblocks 无关。恕我直言,现在改变为时已晚。
    • @LazyOne File>Settings>File templates>PHP Field Doc Comment
    • @an1zhegorodov “很遗憾,PHPStorm 无法识别 @type 标签” 现在可以了——在下一个公共版本中可用。在任何情况下:提到的 WI-6027 现在已修复,因此如果您的工厂通过 static 调用完成,您可以使其工作:confluence.jetbrains.com/display/PhpStorm/…
    【解决方案3】:

    建议的方法是先放通用类型(如果你的工厂创建了特定类型的子类型,那么这就是类型),然后你可以添加所有子类型(或重要的子类型)。

    这通常与 PHPStorm 配合得很好,而且根本不违反 PHPDoc。

    /**
     * @return M_TransactionObject|M_UserObject|M_Foo|M_Foo1|M_Foo2|M_Foo3|M_Bar|M_Bar1|M_Bar2|M_Bar3
     */
    

    这太过分了。我通常使用 @return 标记的(子)类型不超过三种。我会说这是一个很好的经验法则。

    例如:

     * @return M_UserObject|M_TransactionObject
    

    在我看来还可以。一个类似的提示动作是:

     * @return array|string[]
    

    * @return Iterator|string[]
    

    第一种类型表示已定义的用途(例如,最后一行是getIterator()IteratorAggregate),替代类型对于解决IDE-Typehinting 的缺陷很有用(PHPStorm 永远不会少用这个)。

    HTH。 @ircmaxell 写的没有错,但是如果您将第一个返回类型保留为他的意思(接口在那里),只要您了解替代类型仅用于类型提示,您就可以了。如果一个工厂方法返回许多不同的“类型”,所有这些都应该共享一个接口。这个很重要。例如,如果您看到一长串列表,则应该有一种类型,而这种类型就是接口。

    【讨论】:

    • 为什么一个工厂要从不同的层次结构构建对象?对我来说,拥有单独的工厂 foreach 层次结构听起来更合乎逻辑和干净。
    • 希望我没有写那个,因为那不是我的意图。通常,工厂应该从一个层次结构中构建对象。因此基本类型,通常作为接口。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2011-11-20
    • 1970-01-01
    相关资源
    最近更新 更多