オプションの依存関係は不要

この投稿では、 PHPパッケージアルコール依存症について説明します 。 むしろ、composer.jsonで定義されている、いわゆるオプションまたは提案された依存関係(オプションの依存関係、suggest / dev-dependencies)についてです。

中毒とは何ですか?


そもそも、依存関係とは何か、それが何であるかを扱います。 次のコードがあります。

namespace Gaufrette\Adapter; use Gaufrette\Adapter; use \MongoGridFS; class GridFS implements Adapter { private $gridFS; public function __construct(MongoGridFS $gridFS) { $this->gridFS = $gridFS; } public function read($key) { $file = $this->find($key); return ($file) ? $file->getBytes() : false; } } 

GridFSクラスは、ある程度変更したGaufrette 抽象ファイルシステムライブラリの一部です。 このコードのすべての依存関係を判断するには、次の質問をする必要があります。



しかし、もう1つ考慮すべき点があります。

  1. エラーが発生しないようにするには、どのバージョンのPHPを実行する必要がありますか?
  2. おそらく、特定のバージョンを追加する必要がありますか?
  3. どのPHP拡張機能が必要ですか?
  4. どのPEARライブラリをインストールする必要がありますか?
  5. 不足しているパッケージは何ですか?

GridFSクラスに戻ると、ネームスペースが使用されているため、PHPバージョンは少なくとも5.3でなければなりません。 また、 \MongoGridFSクラスが\MongoGridFS 。これはPHPのmongo拡張機能であり、この拡張機能のバージョン0.9.0からのみ使用可能です。 すべてがcomposer.jsonを作成しているようです:

 { ..., "require": { "php": ">=5.3", "ext-mongo": ">=0.9.0" } .. } 

このリストで十分であり、アプリケーションでこのクラスを使用することを妨げるものは何もないようです...悲しいかな、これはそうではありません。

有効なknplabs / gaufrette依存関係リスト


前述したように、GridFSはGaufretteライブラリの一部であり、使用されるファイルシステムの詳細を気にすることなく、さまざまな種類のファイルシステムにファイルを保存するための抽象的なファイルシステムレイヤーを提供します。 このライブラリのcomposer.jsonを見てください:

 { "name": "knplabs/gaufrette", "require": { "php": ">=5.3.2" }, "require-dev": { ... }, "suggest": { ... "amazonwebservices/aws-sdk-for-php": "to use the legacy Amazon S3 adapters", "phpseclib/phpseclib": "to use the SFTP", "doctrine/dbal": "to use the Doctrine DBAL adapter", "microsoft/windowsazure": "to use Microsoft Azure Blob Storage adapter", "ext-zip": "to use the Zip adapter", "ext-apc": "to use the APC adapter", "ext-curl": "*", "ext-mbstring": "*", "ext-mongo": "*", "ext-fileinfo": "*" }, ... } 

そして、ここに彼は、最初の驚きです! 依存関係について以前に発見されたほとんどすべては価値がありません、なぜならライブラリは5.3.2以上のPHPバージョンを必要とするだけであり、それ以外のすべて-味覚、オプション、または開発目的のみ-必要なものを呼び出すためです。

もちろん、ComposerやPackagistを長い間使用している人は、すでにそのようなことに慣れています。 しかし、これは間違ったアプローチです。 前にわかったように、ext-mongoはGridFSクラスの真の依存関係ですが、composer.jsonはその逆を示しています。

これは、プロジェクトでこのクラスを使用したい場合、パッケージknplabs/gaufretteを使用するだけでは不十分であることを意味します。 私は自分のプロジェクトでext-mongoも必要にしましたが、これは間違いです。これは、mongo拡張を必要とする私のプロジェクトではなく、 knplabs/gaufretteです。 さらに、どのバージョンのext-mongoを選択すべきかをどのようにして知ることができますか? サジェストブロックに示されている依存関係はこれについて語っていないので、選択する必要があります。

それは別のパッケージです。


knplabs/gaufrette 、このように行動する唯一の人でknplabs/gaufretteなく、提案されているように実際の依存関係を提示します。 パッケージ所有者は、ユーザーが必要とする可能性のあるさまざまなクラスを追加すると便利です。 または必要ありません。 したがって、これらのクラスの使用がオプションの場合、依存関係もオプションです。 ただし、パッケージ所有者は、依存関係がオプションであることを忘れています。 これらはコードなしでは機能しないため、常に必要です。

解決策


この場合、パッケージ開発者は何をすべきですか? それらを分離します。 knplabs/gaufrette場合knplabs/gaufretteこれはファイルシステムから抽象化するために必要なすべての共通コードを含むknplabs/gaufretteパッケージが必要であることを意味します。 そして、GridFSなどの個々のアダプターは、それぞれ独自のパッケージ(たとえば、 knplabs/gaufrette-mongo-gridfsます。 そして、彼はすでに依存関係を持っています。

 { ..., "require": { "php": ">=5.3", "knplabs/gaufrette": "~0.1" "ext-mongo": ">=0.9.0" } } 

そして、それだけです。どこにも隠された依存関係はなく、すべて必要です。

knplabs/gaufretteは、依存関係をまったく持たなくなり、アダプターを含むパッケージのみが提供されます。

 { "require": { "php": ">=5.3.2" }, "suggested": { "knplabs/gaufrette-mongo-gridfs": "For storing files using Mongo GridFS", ... } } 

このアプローチには多くの利点があります。


次回、提案された依存関係をパッケージに追加し、この依存関係がこのパッケージで有効かどうかを考えますか? 次に、パッケージを分離し、必要に応じてこの依存関係を指定します。 メインパッケージ内のすべてのコードが、この提案された依存関係なしで機能する場合、この場合、提案されたものとして示すことができます。

Source: https://habr.com/ru/post/J219837/


All Articles