我有一个Web界面,我将从中收集用户数据(用户名,密码,电子邮件等),后端必须将这些数据提供给其他3个系统(SystemA,SystemB,SystemC)。
供应由3个不同的API完成,每个系统对应一个系统(A,B和C)。
我在后端的当前设计看起来像这样:
interface ProvisionData
{
public function createUser();
public function deleteUser();
public function changePassword();
}
class SystemA_API_wrapper implements ProvisionData
{
public function createUser(){ ... }
public function deleteUser(){ ... }
public function changePassword(){ ... }
}
class SystemB_API_wrapper implements ProvisionData
{
public function createUser(){ ... }
public function deleteUser(){ ... }
public function changePassword(){ ... }
}
class SystemC_API_wrapper implements ProvisionData
{
public function createUser(){ ... }
public function deleteUser(){ ... }
public function changePassword(){ ... }
}
每个System * _API_wrapper都有不同的createUser()(和其余)函数的实现。
在前端,我创建了一种代理类,我使用从Web界面收集的数据来提供它。它看起来像:
class provisionProxy
{
public $sA = null;
public $sB = null;
public $sC = null;
//constructor instantiates all System*_API_wrapper objects
public function __construct() {
$sA = new SystemA_API_wrapper();
$sB = new SystemB_API_wrapper();
$sC = new SystemC_API_wrapper();
}
// proxy function deleteUser calls deleteUser() of each of
// our APIs
public function deleteUser($username, $password) {
$this->sA->deleteUser($username, $password);
$this->sB->deleteUser($username, $password);
$this->sC->deleteUser($username, $password);
}
}
有没有人有任何建议或更好的做法?
(我已经发布了相同的问题,但由于技术问题,我无法登录到我的旧帐户,所以问题会在我的新帐户下修改并重新发布。原始问题可在此处找到:{{3 } - 谢谢)
答案 0 :(得分:3)
基于您无法将三个后端系统更改为全部访问用户管理的中央系统(这会更好)的假设,我建议的唯一更改是您的代理,您需要在其中进行硬编码调用对于您的三个系统中的每一个 - 最好在构造函数中创建ProvisionData对象列表,然后在删除/创建调用中,循环遍历该列表并在每个系统上调用相应的方法。
这意味着,如果在将来的某个时刻,您必须将系统D添加到此,那么可以通过在单个位置进行更改来完成。
(我的PHP技能有点粗糙,因此不会尝试提供代码)。
答案 1 :(得分:1)
设计看起来不错,但是如果你想从抽象中获得任何好处,那么将所有ProvisionData
对象添加到Paddy建议的列表中是绝对必要的。即使三个外部系统是固定的并且永远不会改变,这也适用。此外,将要执行的operation
与执行它的对象(又名Command pattern)分开将使事务支持和撤消行为成为可能。
考虑这个例子 - 由于您需要在所有系统中保持数据的一致性,因此我会猜测会涉及某种交易。如果有createUser()
操作且一个系统关闭,您不希望在其他两个系统上创建用户,因此从代理的角度来看,整个操作都会失败。在列表中处理这些操作比单独检查每个项目更容易。使用列表,伪代码:
/*
* systems object represents a list of systems
* execute() and undo() are methods in the systems object
*
* result represents the result of performing an operation on some systems
* successfulSystems represents systems in which the operation was successful
*/
operation = new Operation("createUser", ["param 1", "param 2", ..])
result = systems.execute(operation);
// if operation failed in any of the systems
if(result.FAILURE) {
// then undo the operation on systems where it did succeed
result.successfulSystems.undo(operation);
}
列表基本上允许将外部子系统整体分组,从而为自己添加另一级抽象,all
和any
等操作比单独检查更有意义。分离操作会带来更多好处。
答案 2 :(得分:0)
您可以使用Observer模式使后端系统可以独立于其编号处理您的前端数据,这可能会发生变化。