Reputation: 347
Imagine we want to use the following library like this:
use GrahamCampbell\GitHub\GitHubManager;
class Foo
{
private GitHubManager $github;
public function __construct(GitHubManager $github)
{
$this->github = $github;
}
public function bar(): array
{
$this->github->issues()->show('GrahamCampbell', 'Laravel-GitHub', 2);
}
}
Does it makes sense to create an interface like:
interface GitHubManagerInterface
{
public function showIssues(): array;
}
Then implement it and bind the implementation to the interface and use it in my code like the following?
class Foo
{
private GitHubManagerInterface $github;
public function __construct(GitHubManagerInterface $github)
{
$this->github = $github;
}
public function bar(): array
{
$this->github->showIssues('GrahamCampbell', 'Laravel-GitHub', 2);
}
}
Or there is a better way to prevent coupling? Or it's over engineering? :)
Upvotes: 0
Views: 146
Reputation: 711
If it's a library, like Redis client or MongoDB client library, it's better to use them in the infrastructure layer. Wrapping them in an interface would make your code decoupled, but sometimes you can't eliminate the dependencies.
In my experience with MongoDB, your interface can get polluted with MongoDB driver models because the library has many models to express the outputs and inputs. Then you have two options:
Sometimes you know that you won't change the 3rd party library. It helps you to accept the coupling to the library. Yes, your project would be coupled to an external library but it won't hurt you as long as you don't want to change it.
But if it's an external service, you should use the ACL pattern to prevent your project from getting polluted with 3rd party services logic. The ACL pattern suggests defining an interface for the 3rd party service with the client models as inputs and outputs and translating the client models to the 3rd party models in the implementation.
Here are some notes to decide whether to wrap a 3rd party library in an interface or not:
Upvotes: 2