Magento 2-マジックゲッターを使用/回避するための良い習慣ですか?


21

Varien_Object(M1)およびDataObject(M2)のマジックゲッターは一般的な方法ですが、Magento 2では使用するのが間違っているように感じます。

良い:

  • 読み書きが簡単

悪い

質問

Magento 2には、2つの新しいメソッドがあります。

  • getDataByKey($key)
  • getDataByPath($path)

まだ使用する正当な理由getData($key)や魔法のゲッターはありますか?


編集:

@Vinaiありがとう。@method私のアプローチはかなり異なっていたので、私は方法に言及しませんでした。

IDEに役立つだけで、他のものには影響しません。

いくつかのmergedf PRがあります。これは、ループの(int)代わりにキャストしintval()たり、ループの外に配列サイズを取得したり(小さな配列であっても)するような「マイクロ最適化」です。

一方、

  1. マリウスが説明したように、いくつかの「オーバーヘッド」を持つ魔法のゲッター....

    strtolower(trim(preg_replace('/([A-Z]|[0-9]+)/', "_$1", $name), '_'));
  2. getData($key) mehtodsも2-3の追加チェックが必要です...

    • if ('' === $key) {
    • if (strpos($key, '/')) {
    • if ($index !== null) {

独自のコードの場合、実際のメソッドを好むことに完全に同意しますが、同じケースではおそらくそうではありません...たとえば、カスタムイベントを作成しました...

$value = $observer->getVar_1();
$value = $observer->getData('var_1');
$value = $observer->getDataByKey('var_1');

3rd withを使用するの/** @var some $value */が最適だと思います。(?)


1
クラスdocブロックにメソッドを追加して、コード分析ツールが存在しないメソッドについて文句を言わないようにすることができます。また、キーに数字を使用すること自体が悪い習慣だと思うので、ここでは「悪い」と表示されるべきではありません。
リリーベルゴンザット

回答:


20

上記の質問には、対魔法のメソッドを使用する方法についてですgetDataByKeygetDataByPath。3番目のオプションもあると思いますが、それは実際のゲッターメソッドとセッターメソッドを実装することです。

getData*すべてのメソッドには、型推論が機能するために注釈を付ける必要があるという欠点があります。
通常、それは呼び出しの/* @var string $foo */上に注釈を付けて行われgetData*ます。
データの型は、を呼び出すクラスではなく、データを含むクラスで宣言する必要があるため、これは少し臭いgetData*です。
その理由は、データが変更された場合、すべてのgetData*呼び出しサイトではなく、クラスが更新される可能性が最も高いためです。
そのため、実際の方法では、getData*アクセッサを使用するよりも保守性が向上すると思います。

したがって、保守性と実装の高速化(記述するコードが少ない)の間のトレードオフに要約されると思います。

幸いなことに、最近のIDEは私たちのためにgetterおよびsetterの実装を作成するのに非常に優れているため、その引数は実際にはもう適用されません。

上記の質問から欠落しているマジックゲッターとセッターに対するもう1つの議論は、それらのプラグインを作成できないことです。

私がトピックに追加できると思う唯一の他の価値@methodは、何らかの理由で実際のメソッドの実装が問題にならない場合、注釈を使用するかしないかの理由を収集しようとすることです。

長所

  • @method注釈は、実際のゲッターとセッターを実装に比べて書き込みに少しのコードです。IDEはアクセッサメソッドの生成に優れているため、最近ではほとんど真実ではありません。そのため、これは実際の利点ではなくなりました。

短所

  • 物事がうまくいかないのは簡単です。
    • 注釈はコメントであり、コードが進化しても簡単に廃止されますが、注釈は更新されません。実際のメソッドはより堅牢です。
    • インタープリターエラーなしで、異なるタイプシグネチャを持つ複数の注釈を追加することができます。静的コード分析の動作は未定義であり、追跡が困難な微妙なバグにつながる可能性があります。
    • @method同じ名前の注釈と実際のメソッドの両方が存在する場合、静的コード分析中に注釈タイプの署名が実際のメソッドをオーバーライドします。これは、PHPインタープリターが行うことの反対です。これも、微妙なバグを簡単に引き起こす可能性があります。

上記の理由により、@method注釈を避けることができる場合、個人的に注釈を使用しません。
長生きすることを目的としたコードの場合、実際のゲッターメソッドとセッターメソッドを実装します。保守性の向上は、IDEをトリガーしてそれらを生成する価値があります。

スパイク中のより実験的なコード、またはモジュールの簡単な実装の詳細については、getData*私は怠け者なのでメソッドも使用します。


いい要約。ヴィナイありがとうございます。それは私が実際に尋ねた以上に答えます。
sv3n

1

getData*すべてのメソッドには、型推論が機能するために注釈を付ける必要があるという欠点があります。

通常、それは呼び出しの/*@var string $foo */上に注釈を付けて行われgetData*ます。getData *を呼び出すクラスではなく、データを含むクラスでデータの型を宣言する必要があるため、これは少し臭いです。

その理由は、データが変更された場合、すべてのgetData*呼び出しサイトではなく、クラスが更新される可能性が最も高いためです。そのため、実際のメソッドではgetData *アクセサーを使用する場合と比べて保守性が向上すると思います。

はい、それは臭いですが、避けることができます(そして、すべきですか?)。これは非常に一般的なコードであり、しばしば提案されると思います:

/** @var Foo $product */
$product = $model->getProduct()
if ($product->getId()) {
    $product->doSomething();
}

問題は、戻り値が呼び出し可能なメソッドを持つ型であると推測することですFoogetId()

保守性のために、変数の型を想定してInvalidArgumentException

$product = $model->getProduct()
if ($product instanceof Foo && $product->getId()) {
    $product->doSomething();
}

これ$model->getProduct()により、戻り値のタイプが異なる場合の静的コード分析も修正されますFoo|false。最初の場合、それはdoSomething()可能な呼び出しについて文句を言うでしょうfalse

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.