我承认,我没有进行单元测试...但我想要。话虽如此,我有一个非常复杂的注册过程,希望能够优化以便更容易进行单元测试。我正在寻找一种结构化类的方法,以便将来可以更轻松地对其进行测试。所有这些逻辑都包含在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模块)。每个提供程序都与用户帐户相关联。
我希望以这样一种方式构建此系统
# 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')
这里有太多决策需要做出……我知道我应该优先考虑组合而非继承,并创建一些接口。我也知道我可能需要工厂模式。最后,我在这里有很多领域模型的事情……所以我可能需要业务领域类。但我不确定如何将它们全部融合在一起,而不是在追求圣杯的过程中制造一个彻底的混乱。
此外,最好的地方去进行数据库查询是哪里?
我已经为每个数据库表创建了一个模型,但我想知道在哪里以及如何实例化特定的模型方法。