PHP静态方法/单例模式

时间:2012-10-04 02:06:34

标签: php oop static singleton phpunit

我正在为我公司的软件产品设计一个新的架构。我对单元测试很新。我阅读了一些关于使用单例和静态方法的恐怖故事,但我并没有清楚地理解使用它们的问题,并且会欣赏一些启示。

这是我正在做的事情:

我有一个多层架构。在服务器端,我使用一系列可重用的对象来表示数据库表,称为“处理程序”。这些处理程序使用其他对象,如XMLObjects,XMLTables,不同的Datastructures等。其中大多数是自制的,而不是预先打包的对象。无论如何,在这一层的顶部是一个伪单一层。其主要目的是简化更高级别的服务器端代码并​​创建无缝的类管理。我可以说:

$tablehandler = databasename::Handler('tablename') 

......得到一张桌子。我没有看到这个固有的问题。我使用一堆处理程序(一个关联数组)来包含不同对象的实例。我没有使用全局变量,所有静态数据库都是受保护的或私有的。我的问题是这是如何导致单元测试的问题。我不是在寻找代表性的言论,我正在寻找因果关系。我还要感谢对此的任何其他见解。在这一点上,我觉得它是一个非常灵活和高效的架构。这里的任何帮助都会很棒。

1 个答案:

答案 0 :(得分:4)

使用静态方法提供对托管实例的访问 - 无论它们是单例,池化对象还是动态实例 - 只要您提供测试注入方法,就不会成为测试问题他们自己的模拟和存根根据需要,一旦完成删除它们。根据你的描述,我没有看到任何阻碍这种能力的东西。只有在你需要的时候才能构建它。

如果你有一个类对没有扩展点或通过实例进行工作的方法进行静态调用,那么你会遇到困难。例如,像这样的呼叫

UserTable::findByEmail($email);

使测试变得困难,因为你无法插入模拟,仅限内存的表等。但是,将其更改为

UserTable::get()->findByEmail($email);

解决了这个问题,因为测试可以在设置代码中调用UserTable::set($mock)。有关更详细的示例,请参阅this answer