【发布时间】:2013-05-25 11:06:16
【问题描述】:
我承认,我没有进行太多单元测试……但我愿意。话虽如此,我有一个非常复杂的注册过程,我想对其进行优化以便于单元测试。 我正在寻找一种方法来构建我的类,以便将来可以更轻松地测试它们。所有这些逻辑都包含在 MVC 框架中,因此您可以假设控制器是根一切都是从那里实例化的。
为了简化,我实质上要问的是如何设置一个系统,您可以在其中管理任意数量的带有 CRUD 更新的第三方模块。这些第三方模块都是 RESTful API 驱动的,响应数据存储在本地副本中。删除用户帐户之类的操作需要触发删除所有关联模块(我将其称为提供程序)。这些提供者可能依赖于另一个提供者,因此删除/创建的顺序很重要。 我对应该专门使用哪些设计模式来支持我的应用程序感兴趣。
注册跨越多个类并将数据存储在多个数据库表中。以下是不同提供者和方法的顺序(它们不是静态的,只是为了简洁而写成这样):
-
Provider::create('external::create-user')在特定提供者的特定步骤启动注册。第一个参数中的双冒号语法表示该类应在providerClass::providerMethod上触发创建。我做了一个一般性的假设,Provider将是与方法create()、update()、delete()的接口,所有其他提供者都会实现它。 这可能是您需要帮助我解决的问题。 -
$user = Provider_External::createUser()在外部 API 上创建用户,返回成功,然后用户存储在我的数据库中。 -
$customer = Provider_Gapps_Customer::create($user)在第三方 API 上创建客户,返回成功,并在本地存储。 -
$subscription = Provider_Gapps_Subscription::create($customer)在第三方 API 上创建与先前创建的客户关联的订阅,返回成功,并在本地存储。 -
Provider_Gapps_Verification::get($customer, $subscription)从外部 API 检索一行。此信息存储在本地。另一个电话被打了,我跳过它以保持简洁。 -
Provider_Gapps_Verification::verify($customer, $subscription)执行外部 API 验证过程。其结果存储在本地。
这是一个非常简单的示例,因为实际代码依赖于至少 6 个外部 API 调用和注册期间创建的 10 多个本地数据库行。在构造函数级别使用依赖注入是没有意义的,因为我可能需要在控制器中实例化 6 个类而不知道我是否需要它们。我想要完成的是类似于 Provider::create('external') 的内容,我只需指定开始注册的起始步骤。
问题的症结
如您所见,这只是注册过程的一个示例。我正在构建一个系统,我可以在其中拥有数百个服务提供者(外部 API 模块),我需要注册、更新、删除等。这些提供者中的每一个都与一个用户帐户相关联。
我想以一种在触发创建新提供者时可以指定操作顺序(步骤)的方式构建此系统。换句话说,允许我指定事件链中接下来触发哪个提供程序/方法组合,因为创建可以跨越很多步骤。目前,我通过主题/观察者模式发生了这一系列事件。我正在寻找可能将此代码移动到数据库表provider_steps,我在其中列出每个步骤以及它在success_step 和failure_step 之后(用于回滚和删除)。该表如下所示:
# the id of the parent provider row
provider_id int(11) unsigned primary key,
# the short, slug name of the step for using in codebase
step_name varchar(60),
# the name of the method correlating to the step
method_name varchar(120),
# the steps that get triggered on success of this step
# can be comma delimited; multiple steps could be triggered in parallel
triggers_success varchar(255),
# the steps that get triggered on failure of this step
# can be comma delimited; multiple steps could be triggered in parallel
triggers_failure varchar(255),
created_at datetime,
updated_at datetime,
index ('provider_id', 'step_name')
这里有很多决定要做...我知道我应该更喜欢组合而不是继承并创建一些接口。我也知道我可能需要工厂。最后,我这里有很多领域模型问题......所以我可能需要业务领域类。我只是不知道如何在追求圣杯的过程中将它们全部融合在一起而不造成一团糟。
另外,数据库查询发生的最佳位置是哪里?
我已经为每个数据库表建立了一个模型,但我想知道在哪里以及如何实例化特定的模型方法。
我一直在阅读的东西......
【问题讨论】:
标签: php oop unit-testing design-patterns dependencies