例如,我有一个函数,它在变量中的两个其他字符串之间获取一个字符串.我一直在考虑将它移动到String_Helper类,或类似的东西.此功能已经变为静态.
另外,我有一个查询数据库,查询($sql)的函数.连接细节由实例提供,但我一直在考虑将其设置为静态,并使用查询($sql,$connection).然后开发人员可以静态地调用它,而根本不需要实例化数据库类.
对我来说,问题是:
>做这样的事情值得吗?像查询函数这样的函数让我想知道这不仅仅是我试图让一切尽可能地保持静态,而没有任何实际需要.在什么情况下你会认为这有用吗?
>我知道静态函数更难测试,但如果我确保他们的代码完全无依赖(或在必要时使用依赖注入),那么它们就像其他所有东西一样容易测试吗?
>目前这不是一个问题,但如果将来我决定使用静态函数扩展类,那么我将无法使当前代码使用我的扩展函数.我想过Singletons,但同样的问题出现了:代码将调用Singleton_Class :: getInstance(),而不是My_Extended_Singleton_Class :: getInstance().依赖注入似乎是解决此问题的唯一方法,但它可能会导致一个笨重的API,因为必须将每个依赖项赋予__construct()上的对象.
>我有一个容器类,它静态地保存某些信息,以便可以在脚本中的任何位置访问它们(全局范围).如果我不能使用静态函数或单例,那么包含不同变量实例的类就会很棒.可以使用例如Container :: $objects [‘MyClass’] = $MyClass_object;,然后其余的代码可以只访问Container :: $objects [‘MyClass’].如果我扩展了MyClass类,我可以使用Container :: $objects [‘MyClass’] = $MyExtendedClass_object;,而使用Container :: $objects [‘MyClass’]的代码将使用MyExtendedClass,而不是MyClass.在我看来,这是迄今为止最好的方法,但我想知道你对它的看法.
1.值得做这样的事情
是的,不是.将辅助函数拆分成自己的类是个好主意.它保持每个类的“范围”严格定义,并且你不会得到坍塌.但是,不要因为可以使方法静态.查询方法是通过管理连接使您的生活更轻松,那么为什么您想要失去这种好处?
他们更难测试
它们并不难测试.依赖于状态的静态方法更难测试(访问静态成员变量或全局变量).但是静态方法通常和实例方法一样容易测试(事实上,它们可以更容易,因为您不需要担心实例化).
3.扩展课程
这是一个有效的问题.如果你把String_Helper :: foo()放在类本身,你会遇到问题.但是一个选项是将字符串帮助器的名称设置为类变量.那么你可以做{$this-> stringHelper} :: foo()(注意,仅限PHP 5.3).这种覆盖类的方法,您需要做的就是更改该实例中的字符串帮助程序类. Lithium
框架做了很多……
4.全球登记处
我会远离这个.你基本上只是让每个班级都成为单身人士而不强制执行.由于您现在依赖于全球范围,测试将是一场噩梦.相反,我将创建一个注册表对象,并通过构造函数(依赖注入)将其传递给类.您仍然可以完成同样的事情,因为您有一个对象/类的存储,但您不再依赖于全局范围.这使测试更容易.
一般来说
当你正在考虑做这样的事情时,我喜欢在遇到这样的问题时停下来.停下来坐下来思考*我试图解决的是什么实际问题?“.明确列举问题.然后拉出你想要的解决方案,看看他们是否真的解决了问题.如果他们这样做了,那就考虑一下未来以及是否有解决方案从长远来看是非常可维护的(从错误修复的角度来看,以及关于功能添加的内容).只有当你对这两个答案感到满意时,你才应该考虑这样做.哦,还记得保持简单编程不是要制作最复杂,最聪明或最神奇的解决方案.它是关于制作解决问题的最简单的解决方案……
我希望有帮助……
祝好运!