首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP:我应该创建这个类的对象,还是静态的可以接受?

PHP:我应该创建这个类的对象,还是静态的可以接受?
EN

Stack Overflow用户
提问于 2013-06-01 18:49:20
回答 3查看 252关注 0票数 0

我有一些关于这个项目的最佳实践和性能的问题。原谅我这么大的问题。

目前,我正在用PHP和MySql构建一个基于文本的游戏,到目前为止,核心文件中大约有2,500行。目前,这是一个完全模块化的函数库。有些用于数据访问,有些用于数据操作,等等。

我的第一个问题是这个:一个类ItemManager包含几十个专门用于在数据库中添加、更新和删除游戏项目的方法。这些方法唯一的共同点是它们与数据库交互。当前,构造函数请求一个mysqli对象,然后在其所有函数中使用该对象。但是,一旦我将MongoDB添加到项目中,其中一些函数可能与不同的数据库交互。

简单地使所有这些功能都是静态的是可以接受的还是更好的呢?我认为没有理由在只有一个对象的情况下实例化对象,也不需要它维护类成员。那么,我是否应该使用静态方法呢?为什么?

第二个问题:有人能帮助我理解除了模块化之外在PHP中使用类的好处(因为我可以通过函数文件实现同样的效果)吗?来自Java背景,我认识到OOP在持久环境中的好处,因为对象在整个应用程序的生命周期中维护数据和状态。但是,使用PHP,脚本的生命周期只是一秒的一小部分,所有的状态信息都存储在数据库中。几乎所有的函数都只是操纵数据库,那么目的是什么呢?当我只调用函数时,实例化对象不是毫无意义吗?我可以只做包含分类数据操作类的静态类,而不实例化类的对象吗?,为什么我应该在函数文件上使用类?基本上不是一样的吗?完全静态函数可以接受吗?

谢谢你抽出时间,我不知道如何把这个问题减少到更少的文本,所以我道歉。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-01 19:26:25

简单地使所有这些功能都是静态的是可以接受的还是更好的呢?我认为没有理由在只有一个对象时实例化对象。

如果您只想做这个类能够做的事情,就没有理由实例化对象。通过使用静态方法,通过对整个代码库中的类名进行硬编码,可以将所有客户端代码与类耦合起来。如果在以后的某个时候,您决定可能需要一个不同的项目管理器服务来满足您的请求,那么您肯定会度过糟糕的一天。

请注意,“另一项管理器”可以是“用于单元测试其余代码的模拟管理器”的简单代码。因此,即使在永远不支持替代方案的情况下,使用这样的静力学也会使您的代码几乎无法测试。

当然,您已经提到很可能存在一个不同的项管理器:如果当前的项目管理器接受mysqli对象,那么显然在管理器代码和mysqli接口之间没有抽象层。如果您想使用不同的对象连接到Mongo,那么当前的项管理器代码将如何支持这两种配置?你不需要写一个新的项目管理类吗?如果类名到处都是硬编码的,那么如何将其与其余代码集成呢?

让我们从另一个角度来看情况:static给您带来了什么?

显然,它使项目管理器成为一个“单例”对象,这听起来可能是个好主意,因为“只有其中一个”。这种想法在PHP中是不可忽视的(就像在其他语言中,支持多线程,并且存在隐藏的跨线程依赖关系),但它仍然站不住脚。如果您希望您的项目管理器是一个单例,那么就不要创建第二个实例。如果出于某种原因要强制执行此操作,请使用静态变量来计数实例化,如果尝试多个实例化,则抛出。最后,将类设置为final,这样就不能消除这种限制。其结果是:一个不是static的单例。

这就是static所做的一切,鉴于以上所述,站起来作为一个论点是非常脆弱的。

它没有必要维持班级成员。那么,我是否应该使用静态方法呢?为什么?

我不知道这意味着什么--你说构造函数已经需要一个数据库驱动对象,它完全有权利成为类成员。这是另一个明显的暗示,静态不是这里的方法。

有人能帮助我理解除了模块化之外在PHP中使用类的好处(因为我可以通过函数文件实现同样的效果)吗?

我不打算在这里为OOP提出明显的论据,而是提出一个相反的观点:您可以实现相同的运行时效果,但您肯定不能达到应用程序相同的可维护性和可调试性水平。为什么要使用劣质的解决方案呢?

来自Java背景,我认识到OOP在持久环境中的好处,因为对象在整个应用程序的生命周期中维护数据和状态。但是,使用PHP,脚本的生命周期只是一秒的一小部分,所有的状态信息都存储在数据库中。几乎所有的函数都只是操纵数据库,那么目的是什么呢?当我只调用函数时,实例化对象不是毫无意义吗?

一个过程的寿命是一秒的一小部分。代码库的寿命以月、年和几十年为单位。这就是人们将维护它的时间,这也是我们首先使用OOP的原因。

全局变量可以像类成员一样保持状态,在“面向对象”这个术语出现之前很久,人们就一直在维护状态。OO的好处在于管理代码源代码级模型的复杂性,我肯定不同意将其描述为毫无意义。

票数 0
EN

Stack Overflow用户

发布于 2013-06-01 18:59:07

那么,我是否应该使用静态方法呢?为什么?

静态方法通常访问静态变量,这些变量是全局状态(在这方面它们与全局变量没有什么不同),这些变量是不好的,原因很多。

此外,虽然一个对象实例可以被具有相同接口的其他对象替换,但是仅仅通过将另一个对象传递给使用它的函数,静态方法很难被替换。因此,您无法模拟它们,使用它们的代码也不容易进行单元测试。

如果可以的话,不要使用静态方法。

票数 0
EN

Stack Overflow用户

发布于 2013-06-01 19:00:00

1)与对象保持一致,因为它很容易被其他db驱动程序替换或扩展(例如,您可以重写一些函数,以便为特定的getter透明地重定向到MongoDB )。如果您确信将只使用一次实例,则使用单例,甚至更好的是正则模式。

2)的寿命并没有那么短。它使用MVC模式处理引导、路由、模型、业务逻辑和输出。因此,虽然单个请求可能只需几秒钟,但它可能涉及数百个类和数千个方法。

为了坚持您的RPG示例:有一天,您可能会决定让它成为多人游戏。现在您可以实例化第二个player对象,也可以调整大约500个函数。前一个只能通过类.才能实现。

--一个很大的原因是人的限制:不太可能记住成千上万个函数的含义,特别是在团队工作时。通过使用对象,您可以定义瘦API。如果player对象具有公共方法add_item(\item $item)和remove_item(\item‘$item),就不需要记住所有这些检查、计算和db处理函数。您甚至可以要求其他开发人员“创建一个只需要一个攻击()方法的\monster项目”。仅此而已,你已经完成了,合作在最好的时候起作用。

结论如果你来自Java背景,并且了解OOP,不要三思而后行放弃这个习惯。PHP不是scriptkiddies使用的预OO脚本.这是一个成熟的OO环境--但这取决于你是否利用了这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16876097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档