I was asked to create a class that will connect to a remote service via soap. The class has only one public method send(recordName)
.
The class ended like this:
private recordName;
private recordId;
public send(recordName)
{
this.recordName = recordName;
this.validateRecordName();
this.retrieveRecordId();
if (this.recordExists()) {
this.updateRecordOnRemoteServer();
} else {
this.addRecordOnRemoteServer();
}
}
private validateRecordName()
{
// throws exception if this.recordName does not meet certain criteria
}
private retrieveRecordId()
{
response = // creates a soapClient, sends the recordName, and returns a response
this.recordId = response->id ? response->id : null;
}
private recordExists()
{
return this.recordId !== null;
}
private updateRecordOnRemoteServer()
{
someSoapClient->update('url', this.recordId); // notice the this.recordId reference
}
// omitting add method for brevity.
But my boss (who has like 10 years more experience than me), told me I should pass the recordId as a parm to the update method, because otherwise the class suffers from a Orders Matter
issue, and the update method is fragile, since it requires data that is set outside itself (retrieveRecordId()), and that has to be invoked by other method (in this case send()).
So the changes are really slight:
public send(recordName)
{
// unchanged
this.recordName = recordName;
this.validateRecordName();
// changed. Notice recordId is now a method var, not a class member.
recordId = this.retrieveRecordId() // returns the id or null
recordExists = recordId !== null;
if (recordExists) {
// notice the param is being passed
this.updateRecordOnRemoteServer(recordId);
} else {
// add new record
}
}
I read Clean Code by Robert C. Martin, and most of his examples ended similar to what I proposed originally. He will initialize class memeber variables in the public method by invoking private methods, and those attributes will be used by other private methods; all in cascade.
When I first read the book I wasn't convinced it was "that clean" because I also thought that the class relied heavily on the invocation order of the private methods; but I started using that pattern in my own projects and I found it was helping me a lot to keep my code shorter and my public methods super readable.
I also learnt from the book to avoid passing params to private methods (unless there is no other way like sum(a, b), sub(a, b) kind of functions). 95% of the time he won't define arguments for private methods.
I would really like to know if there is a better approach. Thank you!