【问题标题】:Use common functions and views for web database applications使用 Web 数据库应用程序的常用功能和视图
【发布时间】:2011-07-23 09:07:14
【问题描述】:

我正在和一位同事讨论设计问题。

我们正在实现一个 PHP MySQL 数据库应用程序。在第一个实例中,我们为特定表编写了 Insert Get Update Delete、SelectAll 和 Search 函数,在代码中编写了表和字段名,以及几个 php 文件,一个用于对象类,一个用于绘制 HTML 表表,一个用于编辑该表的一行,一个包含上述函数等。

分歧来自于我现在编写了从数据库读取/写入的通用函数,并以表名作为参数绘制 HTML,让这些函数从数据库或类中发现字段名。因此,现在该代码可以用于任何表,任何字段,而无需手动更改需要更改的每个函数。我知道在某些情况下需要更多特定于表的功能,我认为这应该在需求出现时完成,并尽可能集成公共部分。

另一方面,我的同事坚持我们应该为每个表保留一组文件,即每个表大约有 5 个 php 文件。在每种情况下,读/写函数的编写方式不同,所有表所需的任何更改都需要影响 5 x 表数量的次数。

我可以肯定地说,数据库中至少有 15 个以上的主表需要基本功能。

您认为哪种方法最合适?

【问题讨论】:

  • 为什么你的同事坚持要为每个表保留一组单独的文件?
  • 他说,对于每个表和用例,数据访问和可视化将有很大不同,将表名、类名或字段名等作为参数传递的变量,而不是仅仅在 SQL 语句中明确写出,将最终需要太多的 if/switch 结构来管理,并且为每个表保留一组不同的代码,即使是“SELECT * FROM Table”和绘制 HTML 表这样的事情,从长远来看更容易维护。
  • @alex:他说的对吗?他知道什么你不知道? (我与顽固的设计师和程序员打交道的一般规则是,在我理解他们的无知之前,我认为自己对他们的理解一无所知。)
  • 如果是这样,我无法理解为什么会出现这么多“框架”。我通常认为这是自然的进展。结果,我不打算为自己构建一个成熟的框架或 phpMyAdmin,而是逐步实现必要的功能,使事情尽可能通用而不是太复杂,而不是复制和粘贴具有不同字段名的相同功能每个新表。
  • 我们决定先不使用现有的框架,尽管我们快速浏览了一些,因为我们有一段时间没有做过 PHP 项目并且不想了解在我们展示 2 个表格之前,框架的特定架构和库。如果我们更熟悉他们的工作和方式,我们可能会转向一个。

标签: php mysql database-design web-applications


【解决方案1】:

编程的重要原则之一是 DRY:不要重复自己。因此,多个用例共有的所有内容都应该在一个位置编写一次。

现在,我从来不需要开发一个应用程序,其中每个数据库表都具有相同的通用 crud 页面。如果是这样,它就不是一个功能应用程序,而是一个数据库管理应用程序。你确定你不是在重新开发 phpMyAdmin 吗?

【讨论】:

  • 不,我不是在开发 phpMyAdmin,但首先需要做的第一件事是显示一个表格并编辑每一行。我知道典型的选择之外的任何东西都需要特定的 SQL 查询,以及与之配套的视图。但即使在可能的情况下,我相信如果重复这样的用例,那么应该重新实现它的代码以允许它在多个位置使用。我的同事说我们应该有单独的全选。在单独的 .php 文件中为每个表获取、插入、更新、删除函数。
【解决方案2】:

如果您需要相同的代码来处理多个表上的多个基本操作,我会说您不应该多次编写该代码:无需重复自己

  • 编写应用程序需要更多时间
  • 维护它会花费更多时间(并可能导致更多错误)


一个可能的解决方案是将尽可能多的通用代码放入一个类中,该类对许多表都是通用的;然后,为每个表设置一个特定的类,该类将扩展该公共类。

这边:

  • 通用代码只写一次
  • 每个表都可以有其特定的代码
  • 如有必要,可以覆盖特定表的通用代码。

关于这一点,请参阅手册的Object Inheritance 部分。


关于这个通用类的想法,如果你的 CRUD 足够通用,你甚至可以走得更远,并且几乎不需要编写任何代码:有 ORM 框架可以为你做到这一点。

例如,您可能想看看Doctrine

【讨论】:

    【解决方案3】:

    我们正处于开发的第一阶段,对于我们正在开发的网络应用程序,我们没有完整的功能规范。是的,我们知道,但这不是我们的错。

    因此,我们正在构建一些部分,以保持它们非常简单和直接,这样当我们对要构建的内容有更多详细信息时,我们就可以在此基础上进行构建。

    我们有一个面向客户、广告、用户的部分......我想将这些内容分开,因为我们不知道未来会发生什么。是的,目前我们只有几个字段和一些基本的列表和编辑页面,但所有这些都会增长。

    并不是我不想实现一些我们可以重用的通用代码。只是我们还不知道在不久的将来会有什么限制,而且我不想编写我们必须大量参数化的通用代码。

    例如,Alex 构建了一个通用的 Update 方法,您将一个对象传递给该方法,它将创建一个 UPDATE SQL 语句并执行它。好的,这很酷,但这不适用于 Web 应用程序的“用户”部分,因为我们存储了编码的密码。首先,它不会对密码进行编码。其次,如果您编辑用户并且未在密码和密码确认字段中输入任何内容,则旧密码将保留。所以,我们对通用 Update 方法有一个问题,我认为有两种可能的解决方案:

    a) 对 Update 方法进行参数化,以便在修改用户时,如果对象上的密码为空,则保留密码。当然,还要对密码进行编码。

    b) 覆盖子类的 Update 方法。

    Alex 的实现没有使用继承,他在静态类中使用了泛型方法,他会以这种方式调用DataAccess::Update($object);。该方法从类名中获取表名,因为他修改了数据库以使它们匹配(我更喜欢表的“客户端”和类的“客户端”)。所以,选项 b 在 Alex 的实现中是不可能的。

    我尝试构建它的方式是为每个表保留单独的更新方法。是的,我在重复自己,但正如我之前所说,我们没有完整的规范,所以我们不知道它会如何发展。我们有一个想法,但我们没有确切的细节。

    所以,这里的重点是,在我们有更详细的规范之前,我不想编写通用代码,这样我们就可以评估哪些可以在各个部分之间共享,哪些不能。

    并非网络应用程序的所有部分都以相同的方式工作,正如 JB Nizet 所说:“如果是这样,它就不是一个功能性应用程序,而是一个数据库管理应用程序。”

    我可以肯定地告诉你,这不是一个数据库管理应用程序,尽管 Alex 会说“我们只是在构建一个数据库应用程序”。好吧,也许吧,但数据库应用程序不仅显示/修改表。而现在,视图并不能解决所有问题。

    再次,正如 JB Nizet 所说:“如果是这样的话,它就不是一个功能性应用程序,而是一个数据库管理应用程序。”

    现在我又在重复自己了,但这一次没有理由这样做。

    感谢您的宝贵时间。

    【讨论】:

    • 好吧,既然辩论现在已经公开,我不得不说,即使你的论点看起来很合理,但这里的根本缺陷是你认为我的意思是:
    • ——我第一次努力进行泛化,以在所有不可预见的情况下完美地工作。 - 永远不要期望必须为特殊情况编写特殊代码。我一直认为特殊情况需要一些努力,但是我相信这不会大于即使公共功能分开的情况下所需的量。 IMO 将通用代码保存在一个地方的好处远远超过了这种担忧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 2017-12-03
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 2021-05-25
    相关资源
    最近更新 更多