+3  A: 

Based on the assumption that you can't change your three backend systems to all access a central system for user management (which would be better), the only change I would suggest is for your proxy, where you are hard coding calls to each of your three systems - it would be better to create a list of ProvisionData objects in your constructor and then in your delete/create calls, loop through that list and call the appropriate method on each.

This means that if, at some point in the future, you have to add system D to this, then that can be done with a change in a single place.

(My PHP skills are a bit ropy, so won't attempt to provide the code).

Paddy
yes.. your assumption is correct, I can't change my 3 backend systems :(
Jason
Then there's just my note about the proxy. The way you have it coded at the minute is kinda making no use of your interface.
Paddy
yup.. and it's a nice comment.. I'm thinking of creating a pool in which i would register all systemXXX api and then loop through them..
Jason
A: 

You can use Observer pattern for making your frontend data be processable by backend systems independently from their number, which might change.

Gabriel Ščerbák
+1  A: 

The design looks good, but adding all ProvisionData objects to a list as suggested by Paddy is absolutely must if you want to get any sort of benefits out of your abstraction. That applies even if the three external systems are fixed and will never change. Additionally, separating the operation to be performed from the object that performs it (aka Command pattern) will make transactional support and undo behavior possible.

Consider this example - Since you would require consistency of data across all your systems, there will be some sort of transactions involved is my guess. If there's a createUser() operation and one system is down, you wouldn't want the user to be created on the other two systems, so the entire operation should fail from your proxy's point of view. It's easier to deal with these operations in a list vs individually checking each item. With a list, in pseudocode:

/*
 * 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);
}

A list basically allows grouping external subsystems as a whole thus adding another level of abstraction for yourself, and operations such as all and any start making a lot of sense than individual checks. Separating the operation adds further benefits.

Anurag