禁止されているコードの変更、または1台のクレーンの修理履歴の継続


この記事は、以前に公開された記事の続きであり、 ここにあります

この記事では、後方互換性ポリシーによって課された制限にもかかわらず、コードとして妥協しない方法に、より注意を払います。 また、互換性のない変更が元に戻されるまでリファクタリングを遅らせるのではなく、コードの変更中に継続的なリファクタリングを実行します。 コードが変更されるたびに実行される継続的なリファクタリングのみが、コード設計とアプリケーションアーキテクチャの継続的な改善につながり、コード全体の拡張性とサポートの改善につながります。

後のリファクタリングを遅らせると、技術的負債が増加し、製品所有者にとってビジネス価値のないリファクタリングのユーザーストーリーが作成されます。したがって、そのようなタスクは製品バックログのトップにはなりません。

禁止されているコードの変更とそれらの回避方法


クラス/インターフェースの削除


クラスまたはインターフェイスを削除する代わりに、このエンティティに@deprecated注釈を付けます。 また、このエンティティのすべてのメソッドを@deprecatedとして@deprecatedし、すべてのIDEがすべての非推奨メソッドを正しく強調表示するようにします。

エンティティが@deprecatedなった理由は、注釈の後に示す必要があります。 @seeアノテーションを使用して、推奨されていないAPIの代わりに使用する新しいAPIを推奨する必要があります。
 /** * @deprecated because new api was introduced * @see \New\Api */ 

@deprecatedコードが削除される製品のバージョンを事前に知ることはできません。計画が変更される可能性があるため(アジャイル)、コードが関連しなくなったバージョンのみを知ることができます。
したがって、パブリックコードを変更する計画についてサードパーティの開発者に通知するために、 @deprecatedアノテーションとともにトークンを追加します
例のように:
 /** * @deprecated since 2.1.0 * @see \Magento\Framework\Model\ResourceModel\Db\AbstractDb::save() */ public function save() { // ... } 

また、このマーカーは、コードを作成するプログラマーが手動で設定するべきではありません。コードがどのリリースまたはパッチに入るかわからない可能性があるためです。 また、プレリリースビルドを実行する自動スクリプト。 したがって、現在のリリースで提供される新しいコードのために、ビルドツールが添付されます。

パブリックメソッドまたは保護されたメソッドの削除


パブリックコントラクトまたは継承コントラクトとして機能するメソッドを削除する代わりに、メソッドを@deprecatedとして解析する必要があります。 この場合、メソッドコントラクトを保存する必要があります。

クラスまたはインターフェースに新しいメソッドを追加する


Magentoは、インターフェイスがAPIまたは拡張ポイント(SPI)としてどのように使用されるかを知らないため(詳細については、 パート1を参照)、新しいメソッドをコントラクトに追加することも、インターフェイスが使用される場合、後方互換性のない変更(以下BiCと呼びます)ですSPIのように、すなわち サードパーティの開発者(以降3PDと呼びます)は、その実装を提供し、DI構成を介してすぐに実装を置き換えます。 エンティティコントラクトに新しいメソッドを導入することにより、新しいコントラクトの実装を持たない3PDクラスに問題をもたらします。

クラスの場合-誰かがこのクラスを継承し、そのコントラクトを拡張すると、常に名前の衝突が発生する可能性があります。

この場合、次のものが必要です。


静的関数の削除


オプションのパラメータを含むパラメータをパブリックメソッドに追加する


3PDは引き続き継承ベースのAPIを使用し、コントラクトを拡張することでMagentoクラスを継承できるという事実に基づいて、メソッドにパラメーターを追加すると、後継クラスを壊し、元のコントラクトにオプションのパラメーターを追加することになる可能性があります。

古いメソッドのコードを変更する代わりに、変更されたビジネス要件を満たす新しいメソッドシグネチャを示す新しいインターフェイスを導入する必要があります。
さらに、「新しいメソッドをクラスまたはインターフェイスに追加する」の段落で説明されている手順を参照してください。

保護されたメソッドにパラメーターを追加する


メソッドをそのまま保存します。 新しい署名を使用して新しいメソッドを作成し、古いメソッドを@deprecatedとしてマークします。 可能であれば、プライベートとして新しいメソッドを作成します。

メソッドが受け入れる引数のタイプを変更する



メソッドの戻り値の型を変更する


この問題は、コントラクトに存在するメソッドから継承者のクラスまたはインターフェイスのタイプを返すことで解決できます。 しかし、Magentoは新しいコードに継承ベースのAPIを使用することを推奨していないため、この方法は使用しません。

スローされた例外のタイプを変更する


*新しいタイプの例外が古いコントラクトのサブタイプではない場合のみ。

コンストラクターの変更


新しいパラメーターをコンストラクターに追加するには、パラメーターをオプションにし、受け入れられる引数のリストの最後に追加する必要があります。

コンストラクターの本体は、新しい依存関係が渡されるかどうかを確認する必要があり、新しい依存関係が渡されていない場合(渡された引数の値がnull)、静的メソッドMagento\Framework\App\ObjectionManager::getInstance()を使用して依存関係を抽出します。

例:

 class ExistingClass { /** * @var \New\Dependency\Interface $newDependency */ private $newDependency; public function __construct( \Old\Dependency\Intreface $oldDependency, $oldRequiredConstructorParameter, $oldOptinalConstructorParameter = null, \New\Dependency\Interface $newDependency = null ) { ... $this>newDependency = $newDependency ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(\New\Dependency\Interface::class); ... } public function existingFunction() { // Existing functionality ... // Use $this->newDependency wherever the new dependency is needed ... } } 

BCの修正は、KDPVのクレーンのように常にalwaysいように見えますか?


また、コンストラクター渡された古い依存関係を削除することが不可能な場合にリファクタリングする方法はありますが、 追加できるのは新しいものだけです。 したがって、SOLID原則に違反する膨大な数の外部依存関係をクラスが受け入れる場合、Dependency Hellを近づけます。

第一に、新しく作成されたコードの過剰な結合を示す静的テストのエラーの抑制を明確に禁止する必要があります。 つまり このようなSuppressWarningは、バグ修正の実行後または新しい機能の実装後に追加しないでください。



オブジェクト間のカップリングのリファクタリングと依存関係の地獄の防止


たとえば、バグを修正するためにクラスに新しい有効な依存関係を導入し、その後、許容される外部依存関係の数のしきい値を超えた場合( 13 )。

私たちは:


上記の手順を実行すると、 コードの蛇口が新しい色で輝きます。 そして最も重要なこと-契約は変更前と同じままであるため、顧客はこれらの変更に気付かないでしょう!

画像

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


All Articles