如何防止我们的代码与第三方库耦合?

问题描述 投票:0回答:1

想象我们要像这样使用以下库:

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

创建这样的界面是否有意义:

interface GitHubManagerInterface
{
    public function showIssues(): array;
}

然后实现它并将实现绑定到接口并在我的代码中使用它,如下所示?

class Foo
{
    private GitHubManagerInterface $github;

    public function __construct(GitHubManagerInterface $github)
    {
        $this->github = $github;
    }

    public function bar(): array
    {
        $this->github->showIssues('GrahamCampbell', 'Laravel-GitHub', 2);
    }
}

或者有更好的方法来防止耦合?还是工程已经过时了? :)

php laravel design-patterns decoupling design-principles
1个回答
0
投票

如果是库,比如Redis客户端或者MongoDB客户端库,最好在基础设施层使用它们。将它们包装在接口中将使您的代码解耦,但有时您无法消除依赖关系。

根据我使用 MongoDB 的经验,您的界面可能会受到 MongoDB 驱动程序模型的污染,因为该库有许多模型来表达输出和输入。那么你有两个选择:

  • 通过定义模型来包装所需的所有内容,然后在幕后将其转换为 MongoDB 模型,使您的方式变得独立。当然,独立更好,但代价是定义更多模型和编写翻译。
  • 接受耦合并使用第三方模型。这更容易,但代价是依赖图书馆。在开发早期,选择这种方式是合理的(以更快地进入市场),直到您知道您的产品的实际需求是什么以及未来的需求是什么。当您更好地了解您的产品时,您就能更准确地做出决策。

有时您知道您不会更改第 3 方库。它可以帮助您接受与库的耦合。是的,您的项目将耦合到外部库,但只要您不想更改它,它就不会伤害您。

但是如果它是外部服务,您应该使用ACL模式来防止您的项目受到第三方服务逻辑的污染。 ACL 模式建议为第 3 方服务定义一个接口,将客户端模型作为输入和输出,并在实现中将客户端模型转换为第 3 方模型。

以下是一些决定是否将第三方库包装在界面中的注意事项:

  • 你必须衡量破坏向后兼容性的概率。如果该库众所周知并且拥有良好的社区,他们可能会关心用户并支持向后兼容性。因此您的项目不会受到库更改的影响。
  • 您不想更改第 3 方库吗?你不能确定。如果您有多个知名库可以满足您的需求,我认为可以合理地假设您将来可能会更改它。考虑您未来的业务需求。如果您预测您的业务需要及时扩展或改变其需求,这将影响您的决定。
  • 耦合并不总是不好的。因为它可以算作技术债。你欠下的债是为了更快地交付软件。但请记住,总有一天你必须偿还债务。
© www.soinside.com 2019 - 2024. All rights reserved.