gpt4 book ai didi

php - 在自定义 OO PHP 框架中使用接口(interface)

转载 作者:IT王子 更新时间:2023-10-29 00:03:43 25 4
gpt4 key购买 nike

我正在开发一个相当简单的 OO PHP 框架(我猜在这种情况下并不重要……),具有以下基本结构:

application/
classes/
controllers/
includes/
models/
views/
classes/
includes/

我知道使用接口(interface)而不是硬编码类是 OOP 的好习惯,但是当涉及到接口(interface)目录和文件的实际位置/结构时,我不确定最佳实践是什么。

接口(interface)应该在一个目录下分成多个文件:
interfaces/
iDatabase.php
iRouter.php

还是应该将它们都放在一个文件中,因为它们不是那么大:
includes/
interfaces.php (with all Interfaces inside)

使用第一个选项,我可以使用自动加载器来加载接口(interface),而不必在并非所有文件都可以使用的情况下加载每个文件,而使用第二个选项,它们最初都会加载,但这样可以节省我每次加载多个文件的时间。

你怎么看?我是否完全以错误的方式看待这个问题(我倾向于解决我的大部分问题,直到有人引导我走向正确的方向!哈哈)

谢谢堆!

瑞安

编辑 2011-02-07:

在阅读了迄今为止我给出的答案后,我尝试了一些事情。

假设下面的类从磁盘上的确切位置自动加载(Database_Database 将被加载到“classes/Database/Database.php”中),这种设置是否有效?
class Database_Mysql_Database extends Database_DatabaseAbstract implements Database_Database {}

Database_Mysql_Database 是普通类(class), 数据库_数据库摘要是一个抽象类,具有不同类型数据库通用的基本方法, 数据库_数据库将是用户键入提示以确保与他们的类兼容的接口(interface)。

我在正确的轨道上吗?

最佳答案

就个人而言,我建议您将接口(interface)和异常放在语义上合适的地方。没有理由将它们全部放在一个远离类的文件夹中。但同时,不要仅仅为了它而将它们放在具体实现旁边。我举个例子。

假设我们正在处理一个数据库抽象层。您将拥有一个 iDatabase界面,以及 iDatabaseDriver界面。假设你的文件夹(和类)结构是这样的:

/classes/database/idatabase.php
/classes/database/database.php
/classes/database/drivers/mysql/databasedrivermysql.php
/classes/database/drivers/postgres/databasedriverpostgres.php

现在,有 2 个逻辑位置可以放置 iDatabaseDriver .您可以将其放在数据库下或驱动程序下。就个人而言,我会将它放在数据库下,因为它靠近需要的地方(因为 Database 更有可能需要一个 iDatabaseDriver ,因此依赖关系就在那里)。

因此,通过这个,您可以看到有时将接口(interface)放在具体实现旁边在语义上是合适的。但其他时候,将接口(interface)放在依赖项旁边比具体实现更合适。

现在这个例子过于简单化了,但我认为它应该能说明问题。
  • 为接口(interface)的命名和存储制定规则

    想出一个组织代码的系统。这样,它更可预测,更容易自动加载。另外,当您可以根据规则判断某物应该在哪里时,维护起来会容易得多
  • 遵守这些规则!

    这比制定规则更重要。如果你不遵守规则,那比完全没有规则更糟糕,因为你期待一些不会发生的事情。
  • 语义关系优于代码级关系

    接口(interface)与其具体实现之间的语义关系比接口(interface)是接口(interface)的关系更重要。所以将语义相关的代码放在相同(或相似)的地方。

  • 编辑:关于命名和您的编辑:

    就个人而言,我讨厌诸如 Database_Database 之类的东西。 .虽然考虑到应用程序的结构,它可能有意义,但它没有任何语义意义。相反,我喜欢在我的自动加载器中做的是测试文件,如果它不存在但目录存在,则测试该目录内的相同文件。所以, Database将导致检查 /database.php如果失败, /database/database.php .它消除了双重命名的需要。 Database_DatabaseAbstract会变成 Database_Abstract .所以你的 Database_Mysql_Database可以变成 Database_Mysql存储在 /database/mysql/mysql.php (对我来说似乎更干净)。

    至于抽象类的命名约定等,我个人更喜欢通过名称来标识接口(interface)。它使一目了然更容易理解(您知道 public function foo(iDatabase $database) 正在寻找接口(interface)的实例而不是抽象类或具体类)。现在,有两种真正的方法可以做到这一点。
  • 追加 Interface到名字,所以 Database_Database会变成Database_Interface .我个人觉得这对于我的需求来说有点过于冗长,但是这里的好处是所有特殊的类类型(异常、接口(interface)、迭代器等)都可以像这样简单地映射。类名准确地告诉你你拥有什么,没有任何歧义。
  • 在整个序列前加上 i .所以Database_Database会变成iDatabase然后在自动加载器中将其翻译为 /database/interface.php .然后,如果你有更深层次的接口(interface),iDatabase_Mysql_Query也可以工作(这将映射到 /database/mysql/query/interface.php .

  • 就抽象类而言,我不会那样做。类是抽象的这一事实与其语义含义没有任何关系。抽象性质是一种编码构造而不是语义构造(抽象类仅用于继承,因为您使用接口(interface)进行类型检查)。因此我不建议包含 Abstract在类名中。就叫它 Database并完成。它在语义上读起来更好(恕我直言)并传达相同的含义。

    我希望这有帮助并且有意义......

    关于php - 在自定义 OO PHP 框架中使用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4900558/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com