4

1 つのクラスにあまり多くの依存関係があってはならないことを読みました。ある本では、4 つの依存関係は、クラスがやりすぎている可能性があることを示している可能性があると述べています。

10 個の依存関係 (6 つのクラスと 4 つのファサード) を使用するクラスを作成したとします。これらの 6 つのクラスのみを考慮して分割する必要がありますか、それとも 4 つのファサードも考慮する必要がありますか?

誰かが私がどのようにして多くのファサードを取得したか知りたい場合:

use Input;
use App;
use Session;
use Log;

これらはすべて頻繁に必要になります。質問を聞きました - なぜアプリが必要なのですか? 関数を呼び出すには:

App::setLocale('lt');

ここでも、ファサードは依存関係ではないと言う人もいます:

ポリモーフィズムと依存性注入 - 依存性が多すぎる

この問題についてはさまざまな見方がありますが (クラスが何かに依存する場合)、クラスの依存関係は通常、コンストラクターに渡されるもの、つまりクラスをオブジェクトとしてインスタンス化するために必要なものと見なされます。

クラスからファサードを自分で作成できると思います。この方法で依存関係を減らします。しかし、これはあまり意味がありませんか?

たとえば、この記事では、ファサードを使用すべきではないと述べています。

http://taylorotwell.com/response-dont-use-facades/

それから、ファサードがそれほど悪くないことは理解できますが、悪いことは、クラスがあまりにも多くのことをやり始めることです。

私はLaravel 4について話していますが、おそらく同じことがLaravel 5または同じものを使用する他のフレームワークにも当てはまります。Laravel 5 は Laravel 4 ほど多くのファサードを使用していないと聞きました。

アップデート:

また、このトピックについて話し合うときに他の人と使用できるように、そのような議論をしたいと思います. 私が言うように-インターネットの何人かの人(良いスタックオーバーフロープロファイルを持っていても)は、ファサードは悪い、それらはグローバル変数のようなものであると私に言いました、彼らはすぐにわかります-これはグローバルと同じではありません、それらはモック可能です、あなたはすべきではありませんお手入れ。また、彼らは言うかもしれません、これはその人の意見です。だから自分を守るためにストロングポイントが欲しい。だから私はそれを 2*2 = 4 のように説明でき、誰も反対することはできませんでした。または少なくともそれに近い。

アップデート:

それらが依存関係であり、1 つのクラスに対して最大約 4 つの依存関係が必要な場合、グループ化されたクラスを作成するというアイデアは 1 つだけです。クラス ツリーのようになります。しかし、私は小さな機能のために多くのクラスになってしまいます。この 10 個の依存関係のように、最大​​ 4 個の依存関係が必要な場合、1 つではなく 3 ~ 5 個のクラスが必要になると思います。したがって、大きなプロジェクトがある場合は、数百万の小さなクラスが必要になります。もっと複雑に見えませんか?Laravel のように多くのクラスがあるのに対し、CodeIgniter にはクラスがはるかに少なく、読みやすく、フォローしやすく、拡張しやすいように見えます。

4

1 に答える 1

2

Laravel ファサードは間違いなく依存関係です。その使用目的はコントローラーです。サービスとビジネス ロジックを構築するときは、依存関係をできるだけ透過的にする必要があります。

SOLID 実装の実現を目指す場合は、すべての依存関係をパラメーターとして渡すか、クラス コンストラクターで渡す必要があります。

この抽象化を少し説明しましょう。

リファクタリング前

Class PhotoService {

    protected $photosModel = null;

    public function getPhotos()
    { 
        $photos = Cache::get('photos');

        if (is_null($photos)) {
           return Photo::all();
        }
    }
}

まだファサードを使用していますが、IOC を通じて他の依存関係を解決しています

Class PhotoService {

    protected $photosModel = null;

    public function __construct(PhotoInterface $photoModel) {
       $this->photosModel = $photoModel;
    }

    public function getPhotos()
    {
       $photos = Cache::get('photos');

       if (is_null($photos)) {
          return $this->photosModel->getPhotos();
       }
    }
}

IOCで解決

Class PhotoService {

    protected $photosModel = null;

    public function __construct(PhotoInterface $photoModel) {
       $this->photosModel = $photoModel;
    }

    public function getPhotos(CacheInterface $cache)
    {
       $photos = $cache->get('photos');

       if (is_null($photos)) {
          return $this->photosModel->getPhotos();
       }
    }
}

自分のプロジェクト間でコードを共有する場合でも、コードを外部化する場合が私の見解では最良の例です。古いコードを調べたり、ファサードをテストしたりするよりも、インターフェイスを介して完全な署名が提供されている場合、新しい実装が機能する方がはるかに簡単です。

ただし、コントローラーで Facades を使用しても害はありません。

この種のセットアップには、次のような利点しかありません。

  • 頭を悩ますことなくキャッシュ戦略を切り替える機能
  • データベースの種類を切り替える機能
  • ioc を介してモックを注入して機能をオフにする機能
  • 実装の容易さによって tdd を促進します
于 2015-11-01T18:59:59.513 に答える