提问人:Ali 提问时间:11/16/2023 更新时间:11/16/2023 访问量:40
如何防止我们的代码与第三方库之间的耦合?
How to prevent coupling between our code and third party libraries?
问:
想象一下,我们想像这样使用以下库:
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);
}
}
或者有更好的方法来防止耦合?还是过度工程?:)
答:
2赞
R.Abbasi
11/16/2023
#1
如果是库,如 Redis 客户端或 MongoDB 客户端库,最好在基础设施层使用它们。将它们包装在接口中会使代码解耦,但有时无法消除依赖关系。
根据我使用MongoDB的经验,您的接口可能会被MongoDB驱动程序模型污染,因为该库有许多模型来表示输出和输入。那么你有两个选择:
- 通过定义模型来包装所需的一切,然后在后台将其转换为 MongoDB 模型,从而实现独立。当然,最好是独立,但代价是定义更多的模型和编写翻译。
- 接受联轴器并使用第 3 方模型。这更容易,但代价是依赖于库。在开发的早期阶段,选择这种方式(以更快地进入市场)是合理的,直到您知道产品的实际需求是什么以及未来的要求是什么。当您更好地了解您的产品时,您就能更准确地做出决策。
有时您知道您不会更改第三方库。它可以帮助您接受与库的耦合。是的,您的项目将耦合到外部库,但只要您不想更改它,它就不会伤害您。
但是,如果它是外部服务,则应使用 ACL 模式来防止项目被第三方服务逻辑污染。ACL 模式建议为第三方服务定义一个接口,将客户端模型作为输入和输出,并在实现中将客户端模型转换为第三方模型。
以下是一些说明,用于决定是否将第三方库包装在接口中:
- 您必须衡量破坏向后兼容性的概率。如果该库是知名的并且有一个很好的社区,他们可能会关心用户并支持向后兼容性。因此,您的项目不会受到库更改的影响。
- 您会更改第 3 方库还是不会更改?你不能确定。如果您有多个知名库来满足您的需求,我认为可以合理地假设您将来可能会更改它。考虑您未来的业务需求。如果您预测您的企业需要及时扩展或更改其需求,这将影响您的决策。
- 耦合并不总是坏事。因为它可以算作技术债务。您为了更快地交付软件而负债累累。但请记住,总有一天你必须偿还债务。
评论
managers
GitHubManager
GitHubManagerInterface