BACKGROUND
I need to implement an integration with Dropbox using its REST APIs. I don't want to reinvent the wheel so I decided to use Apex Dropbox API Framework. Although it's a bit outdated (it works with v1 Dropbox API), I found the framework to be really useful.
QUESTION
In the examples - Dropbox Sample Apps, I found that both the DropboxTestHarnessController.cls and DropboxAccountController.cls use the same routine to get a valid connector and dropbox client. Below are some part from those classes:
DropboxTestHarnessController.cls
private void init()
{
if (connectorService != null)
{
String msg = connectorService.validateConnector();
validConnector = String.isEmpty(msg);
if (!validConnector)
{
error(msg);
}
else
{
info('Successful authentication. The \'' + connectorService.Connector.Name + '\' connector is being used for authentication.');
}
}
else
{
error('Dropbox connector not found.');
}
}
DropboxAccountController.cls
private void init()
{
if (connectorService != null)
{
String msg = connectorService.validateConnector();
validConnector = String.isEmpty(msg);
if (!validConnector)
{
error(msg);
}
}
else
{
error('Dropbox connector not found.');
}
}
Both these pieces are nearly the same. I understand that the code given in those classes are for example purposes. Whereas my concern is how I can avoid code duplication in my project. Let's say I need to use a dropbox service from 4 apex controllers and repeating the same initialization routine doesn't look good.
I was thinking of creating another service layer that would be responsible for initialization, but I am not 100% sure that it is a correct approach. Again I don't want to reinvent the wheel here and I believe there should be a standard solution (pattern) to this kind of problem, yet I haven't found anything on the Internet that explains it clearly.
UPDATE
To be more specific on the question, let's see how one would use Apex Dropbox API Framework in their code.
public class Example1
{
ConnectorService connectorService;
public ffhttp_Dropbox client;
public Example1()
{
conn = getConnectorService();
init();
}
private void init()
{
// Error hadling dislpayed in the example above
if (connectorService != null)
{
String msg = connectorService.validateConnector();
validConnector = String.isEmpty(msg);
if (!validConnector)
{
// Error
// ...
}
}
else
{
// Error
// ...
}
}
private getConnectorService()
{
// This is omitted for brevity
// ....
// return ...;
}
public List<ffhttp_DropboxModelFile> getFiles()
{
// Exception handling is omitted for brevity
ffhttp_Dropbox client = getDropboxClient();
ffhttp_DropboxFiles files = client.files();
ffhttp_DropboxFiles.FilesListRequest filesListRequest = files.filesListRequest();
return (ffhttp_DropboxModelFile) fileslistRequest.execute();
}
private ffhttp_Dropbox getDropboxClient()
{
if (client == null)
{
ffhttp_Client.AccessTokenCredentials credentials = new ffhttp_Client.AccessTokenCredentials(connectorService.connector.TokenType__c,
connectorService.connector.AccessToken__c);
client = new ffhttp_Dropbox(credentials);
}
return client;
}
}
Now assume one wants to use the Dropbox service in another class "Example2", and then in "Example3" and so on. With the current approach methods init()
, getConnectorService()
and getDropboxClient()
would be copy-pasted into those new classes. This is a kind of situation I want to avoid.