Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

デコレータとサブクラス

最近の記事で、Rails5.1の優れた新機能であるdelegate_missing_toについて触れました。 。 delegate_missing_toを使用 、あるオブジェクトで見つからないメソッドは、代わりに別のオブジェクトで呼び出されます

class Player
  delegate_missing_to :@user

  def initalize(user)
    @user = user
  end

  def points
    Game.points_for_user(user.id)
  end
end

Player.new(user).name # calls user.name

しかし、コメントで述べたGavinのように、これは継承を回避するための奇妙な方法のようです。なぜサブクラスを使用しないのですか?同じ効果が得られ、まったく新しい機能を追加する必要はありません。追加するのは奇妙なことのようです。

delegate_missing_toには理由があるはずです ただし、追加されました。 Rails機能の場合、プルリクエストはこれらの理由を見つけるための優れた方法です。 このプルリクエストで、DHHはこの機能を提案した理由を説明しました:

デコレータを作成する場合の一般的なパターンは次のとおりです。

それは掘り始めるのにかなり良い場所のようです。

なぜデコレータなのか?

デコレータを作成すると、新しいサブクラスを作成せずに、オブジェクトの動作方法が変更されます。 たとえば、以前のコードでは:

class Player
  delegate_missing_to :@user

  def initalize(user)
    @user = user
  end

  def points
    Game.points_for_user(user.id)
  end
end

「プレーヤーは飾る ユーザー」、プレーヤーがほぼ ユーザーのように機能しますが、pointsという追加のメソッドがあります 。そして、それは継承なしでこれを行います。

なぜあなたはこのようなものが必要なのでしょうか?多くのデザインパターンと同様に、他のパターンの代わりにどこで使用したいかが常に明確であるとは限らないため、これは答えるのが難しい質問です。

いつデコレータを使用しますか?

デコレータは、継承を行うためのより複雑な方法である可能性があります。つまり、これらの2行のコードのどちらが優れているのでしょうか?

player = Player.new(User.new(name: "Justin")) # Player decorates User
player = Player.new(name: "Justin")           # Player subclasses User

明らかに2番目ですよね?ここでは、サブクラスではなくデコレータとしてPlayerを作成することは、コードの無駄です。

ただし、オブジェクトを作成した場所から遠く離れた場所で、後でオブジェクトに機能を追加したい場合があります。 たとえば、このようなコードがある場合はどうなりますか?

user = User.find(1)

... some time later ...

player = Player.new(user)

これで、好きな方法で好きな方法でユーザーを作成できます。 Userオブジェクトを作成するコードは、Playerクラスが存在することさえ知らないか気にしません。また、これらの追加のメソッドが不要になった場合でも、元のUserオブジェクトを使用できます。

これは、動作を異なるクラスに分けるのに役立ちます。 各クラスは、特定の状況(プレーヤー、従業員、開発者)でUserオブジェクトがどのように使用されるかに焦点を当てることができます。継承を使用すると、これらすべてのものが簡単に混同されます。

MrChrisは、コメントでデコレータのもう1つの利点について言及しました:

オブジェクトを装飾するときは、そのオブジェクトのパブリックメソッドのみを呼び出すことができます。サブクラス化すると、プライベートメソッドも含め、任意のメソッドを呼び出すことができます。 これにより、サブクラスが親の実装の詳細に誤って依存する可能性があるため、サブクラスがより頻繁に破損する可能性があります。 これらの詳細は通常、パブリックメソッドよりも頻繁に変更されます。

デコレータは、大規模なクラスを分割する場合に特に便利です。デコレータを使用すると、単一責任の原則に従うのが簡単になります。各デコレータは1つのことを実行してうまく実行でき、デコレータを組み合わせてより複雑な動作を実現できます。

Rubyで動作を共有する方法はたくさんあります。サブクラス化したり、モジュールを組み合わせたり、必要に応じて1つのクラスからメソッドを取得して、別のクラスにアタッチしたりすることもできます。ただし、デコレータパターンは、少し異なるものを提供します。 オブジェクト指向言語の構成要素であるインスタンス変数とメソッド呼び出しを使用しているだけです。 これらの基本から、アプリの実行中に柔軟な動作を行うことができます。すべて、コードを過度に複雑にすることはありません。


  1. Discordでユーザーを報告する方法

    Discord は、世界中のゲーマーの間で最も人気のあるプラットフォームの 1 つに成長しました。このように大勢のファンがフォローしていると、不正なユーザーや Discord のルールや規制に違反するユーザーに出くわす可能性があります。このため、Discord にはレポート機能があります。 これにより、プラットフォームに攻撃的または不快なコンテンツを投稿するユーザーを報告できます。ユーザーを報告することは、これらのプラットフォームの神聖さを維持するために、Discord を含むすべてのソーシャル メディア プラットフォームで一般的な慣行となっています。ユーザーや投稿を報告するのは簡単なプロセス

  2. MyIPTV Player のダウンロード方法

    旅行中にお気に入りのテレビ番組を見逃す心配はありませんか? MyIPTV プレーヤーは、インターネットを使用してリモート TV チャンネルを視聴するための人気のある無料アプリです。 フランシス・ビジュモン​​によって開発されました Vbfnet Apps によって公開されています .このメディア プレーヤーは、URL またはローカル ファイルを使用してチャンネルを再生するのに役立ちます。MyIPTV のレビューは、他のそのようなプレーヤーと比較して非常に肯定的です。必要なのはアクティブなインターネット接続だけです。この記事では、MyIPTV プレーヤーをダウンロードし、それを使用してテレビ番組