【问题标题】:Naming of interfaces/abstract classes in PHP 5.3 (using namespaces)PHP 5.3 中接口/抽象类的命名(使用命名空间)
【发布时间】:2009-07-19 15:13:39
【问题描述】:

在 PHP 5.3 之前,我曾经这样命名接口/抽象类:

abstract class Framework_Package_Subpackage_Abstract {}
Framework/Package/Subpackage/Abstract.php

interface Framework_Package_Subpackage_Interface {}
Framework/Package/Subpackage/Interface.php

现在使用 PHP 5.3 并使用命名空间,我不能再使用我的约定了,因为 interface 和 abstract 是保留关键字。

namespace Framework\Package\Subpackage;
abstract class Abstract {}
Framework/Package/Subpackage/Abstract.php

namespace Framework\Package\Subpackage;
interface Interface {}
Framework/Package/Subpackage/Interface.php

那么,我应该如何命名我的类/接口?

【问题讨论】:

  • 自 PHP5 以来abstract/interface 不是保留关键字吗?
  • 是的,他们是;但是,为类使用诸如 Framework_Package_Subpackage_Abstract 之类的名称解决了将这些词单独用作类名的问题。
  • 但到目前为止这还不是问题,因为接口的名称包含用于自动加载目的的整个包路径。

标签: php namespaces naming-conventions


【解决方案1】:

当前的编码指南“PSR-2”基本上建议您将界面放在一个目录下并组合名称。

例如:

File \Vendor\Foo\Interface.php ===> \Vendor\FooInterface.php.

和使用语句例如:

use \Vendor\Foo\Interface; ===> use\Vendor\FooInterface;

见:https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md

【讨论】:

  • 是的,但它增加了更多细节,比如标准来自哪里以及生成文件名的方法。
  • 这确实比公认的答案好得多。一个好的答案应该始终提供解释。
  • PSR-2 不建议这样做。实际上,该指南特别列出了该指南中“类名前缀和后缀”的省略是故意的。 “FooInterface”仅出现在一个示例中,但该指南没有声明它的命名。
  • 所谓的建议部分是链接页面吗?我在那里找不到任何文件命名建议!
【解决方案2】:

关于这个问题(抽象和接口),你可以看看 Matthew Weier O'Phinney 的博客上的帖子“Migrating OOP Libraries and Frameworks to PHP 5.3”——它是关于 Zend 框架的,以及他们如何在 2.0 中解决这个问题。

他们注意到的一件事是:

在其他 OOP 语言中,例如 Python、C#、接口表示为 在接口前加一个大写字母 '一世';在上面的例子中,我们会 然后有 Zend::View::IView。

所以,在你的例子中,我猜你会有这样的东西:

namespace Framework\Package\Subpackage;
abstract class ASubpackage {}
Framework/Package/Subpackage/ASubpackage.php

namespace Framework\Package\Subpackage;
interface ISubpackage {}
Framework/Package/Subpackage/ISubpackage.php

你怎么看? (我还没有测试过这种方式,但它看起来不是一个坏主意?)

【讨论】:

  • 这也是我的第一个想法。 I 代表接口,A 代表抽象。由于我按照 ZF 编码指南进行编码并经常使用 ZF,我感谢您提供这个有趣的链接!
【解决方案3】:

子包摘要, 分包接口

【讨论】:

    【解决方案4】:

    我个人建议避免使用任何匈牙利表示法,并考虑遵循 Java 接口名称标准;也就是说,它们像任何其他类一样被描述性地命名。参见this SO question,了解匈牙利符号的来龙去脉。

    可以在 PHP 自己的 SPL 中找到使用通用、描述性名称来指示功能或行为的一个很好的示例,例如:“Countable”、“Iterator”、“ArrayObject”。

    【讨论】:

    • 这是最好的恕我直言。从名称上应该可以清楚地看出它是一个抽象的通用概念,而不是具体的实现。说到摘要,我确实喜欢在前面加上“摘要”。
    【解决方案5】:

    你也可以这样做:

    src/Chess/Piece.php

    <?php
    
    namespace \Chess;
    
    abstract class Piece implements \Chess\PieceInterface {}
    

    src/Chess/PieceInterface.php:

    <?php
    
    namespace \Chess;
    
    interface PieceInterface {}
    

    src/Chess/Piece/Pawn.php:

    <?php
    
    namespace \Chess\Piece;
    
    class Pawn extends \Chess\Piece {}
    

    这是我在composer.json 中设置自动加载的方法

    {
        "autoload": {
            "psr-0": {
                "": "src/"
            }
        }
    }
    

    【讨论】:

      【解决方案6】:

      老实说,我相信匈牙利符号是用 C# 引入的,因为没有像 Java 中那样的“extends”和“implements”关键字。因此,为了区分约定,就将其称为 IView。在 Java 中,接口单独称为 View,实现称为 DefaultViewImpl、SmartyViewImpl 或类似名称。由于 PHP 确实 具有扩展和实现关键字,因此使用 Java 约定是有意义的。 我听说过这样的论点,即匈牙利符号确实有助于通过查看类名来识别 API 元素。在这种情况下,我会称它为 IView 或 AbstractView。

      【讨论】:

      • 呃,但就像你说的,因为implements 和interface,你的最后一点是无关紧要的。如果我看到class Foo implements Fooer,我不会怀疑Fooer 是否是一个接口。我知道。此外,您不能以任何其他方式使用接口...只有接口可以扩展其他接口,您不能实例化它们,也不能静态使用它们。
      • 最后一点对于浏览 API 文档但不查看代码的人来说是有意义的。
      • 在 C# 之前就引入了匈牙利符号。它的第一个主要用途是在 70 年代与 BCPL 语言一起使用。 C# 又诞生于 2000 年。我记得我们在 90 年代将它与 Delphi 和 C++ 一起使用。
      【解决方案7】:

      在我看来,解决这个问题的最佳方法是简单地将 Class 附加到您的类名中。

      namespace Framework\Package\Subpackage;
      abstract class AbstractClass {}
      Framework/Package/Subpackage/AbstractClass.php
      
      namespace Framework\Package\Subpackage;
      interface InterfaceClass {}
      Framework/Package/Subpackage/InterfaceClass.php

      请注意,这仍然不完美(但是,可以完美运行),但我保持与原始想法相似的代码;)

      【讨论】:

      • 接口不是类。那么为什么是“InterfaceClass”呢?
      • 一年半后,我明白@alexanderpas 的目的了... 将“Class”替换为您正在考虑的基础类名,例如“Class”==“Customer”=> AbstractCustomer .php , InterfaceCustomer.php ...仍然不是理想的IMO,但并不像看起来那么糟糕...
      猜你喜欢
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-06
      • 1970-01-01
      • 2016-03-25
      相关资源
      最近更新 更多