4

複数のビデオを受信し、特定のページに表示する必要があるアプリケーションを使用しています。現在、これらのビデオは、他のプロバイダーを許可しない実装のため、YouTube からのみ取得できます。これは、コードがビデオ データを取得するためです。プレビュー画像として、ビデオの表示を担当する View Helper に直接配置されました。

この構造を変更して、Vimeo などの新しいプロバイダーを簡単に追加できるようにしたいと考えています。また、Strategy パターンが理想的だと思います。View Helper に methodがあり、このsetVideoUrl( string $url )メソッドはgetProviderStrategy( string $url )からメソッドを呼び出します。ファクトリ クラスは、ビデオ URL のプロバイダーのclass VideoProviderFactoryを実装する戦略クラスがあれば、それを返します。interface VideoProvider

どう思いますか?正解です?何かを変更する必要がありますか?

詳細: 最初は戦略を選択するためのスイッチをビュー ヘルパーに直接配置することを考えていましたが、この質問を読んだ後: I Strategy Pattern with no 'switch' statement? 私は自分が間違っていることに気づき、それからclass VideoProviderFactory現れました。

4

1 に答える 1

5

これは、責任が適切に分離された非常に優れた設計のように見えます。

考える材料を増やすために、工場が作成する戦略をどのように決定するかを考えてみましょう。後で別の戦略を追加したい場合、何を変更する必要がありますか? まず、新しい を作成しVideoProvider、次にファクトリswitchステートメントを変更して (説明したように)、この新しい戦略の選択ロジックを含める必要があります。ほとんどの場合、これで問題ありませんが、ファクトリを変更せずに新しい戦略を追加したい場合はどうすればよいでしょうか?

1 つの方法は、URL に基づいて特定のVideoProvider. それを呼びましょうVideoProviderMatcher(疑似コード):

interface VideoProviderMatcher {
  bool understands(url)
  VideoProvider create()
}

これで、このインターフェイスは、URL を理解しているかどうか、およびVideoProviderそれに関連する を作成する方法も認識しています。新しい戦略を作成する必要がある場合は、VideoProviderと関連する の両方を実装しますVideoProviderMatcher。ファクトリに関しては、一連の責任(疑似コード)VideoProviderMatcherを使用して、指定された URL を理解する最初の s とデリゲートのリストをカプセル化するように変更されます。

class VideoProviderFactory {
  List[VideoProviderMatcher] matchers
  void registerMatcher(VideoProviderMatcher matcher) {
    matchers.add(matcher)
  }
  VideoProvider getVideoProviderFor(url) {
    foreach (matcher in matchers) {
      if (matcher.understands(url)) return matcher.create()
    }
  }
}

変更する必要がある唯一のコードは、最初にファクトリを作成するコードです。理想的にはVideoProviderMatcher、ファクトリに入力するために使用する のリストがあり、そのリストに別の項目を追加するだけです。

さて、これは価値がありますか?マッチング ロジックの複雑さ、URL マッチングをビデオ プロバイダーと一緒にカプセル化する意思、新しい戦略が追加されたときにファクトリを安定させたいという希望、および新しい戦略が追加される速度に依存すると思います。ソリューション。

于 2012-04-16T04:10:24.673 に答える