2011-11-24 8 views
5

私は多くのデザイン問題に遭遇しているようですが、私は決して が であることはわかりません。一方で私は頻繁にカップリングを制限しなければならないと聞きましたが、 は1つの責任に固執していますが、私はしばしばそれが難しいと感じます。 to 必要なときにプログラムの一部に情報を取得します。 例えば、原則の原則

class Singer 
    def initialize(name) 
    @name = name 
    end 
    attr :name 
end 

そして歌であるべきである。

class Song 
    def new(singer) 
    @singer = singer 
    end 
end 

又は

class Song 
    def new(singer_name) 
    @singer_name = singer_name 
    end 
end 

後は、より少ない結合を有しているので、原理に従って私はそれを使用すべきです。 しかし、Songの何かが後で 歌手についてもっと知る必要があることを発見した場合、私は悪い方法です。例えば

class Song 
    ... 
    def play 
    puts "Belting it out by #{@singer.name}, winner of 
    #{@singer.grammy_count} grammies!" 
    end 
end 

私は後でソングクラスの代わり 元を使用していた場合、私は修正になるだろう。 しかし、その後、私は誰かがSRP、単一責任 原則を思い出させるし、代わりに示唆している疑いがある:別の歌手が のカバー にいくつかのいずれか他の人のを行う可能性がありますので、

class SongPlayer 
    def initialize(singer, song) 
     @singer, @song = singer, song 
    end 
    def play 
     puts "Belting it out by #{@singer.name}, winner of 
     #{@singer.grammy_count} grammies!" 
    end 
    end 

そしていや、私は、それが理にかなっていると思います歌、そう?しかし、それは本当に同じ の曲ですか?私の場合のほとんどでは決して同じ "歌"ではないので、 その 種類のシナリオはありません。それでSRPは、それが コードにもたらす余分なクラスの価値がありますか?

多くの場合、OOPの原則(SOLIDなど)はJavaの制限である が発生し、Rubyにはあまり適用されません。

答えて

6

カップリングは、別のコンセプトであるcohesionとの間で開催されるべきです。そのうちの1つを極限まで引き上げるのではなく、2つのバランスを取りたいと思っています。あなたの例では、singer_nameSingerに属しているようです。結束を保つために、nameではなく、SingerオブジェクトをSongに渡す必要があります。

より一般的には、このような原則は単にガイドラインにすぎないことに注意する必要があります。あなたは常識と問題のドメインの独自の理解を常に適用する必要があります。まれに明らかなケースがあることはほとんどありません。アプリケーションが成長したり、ドメインをよりよく理解したりするにつれて変化することさえあります。

2

オブジェクト指向プログラムは、実生活オブジェクトをモデル化する必要があります。人生では歌は歌手の名前ではなく、プログラムではこのようにモデル化する必要があります。

すでに@troelsknにはカップリングという概念がありますが、結束という概念もあります。原理は素晴らしいですが、常識が優先されるべきです。

2

ルビーはプログラマの幸福をコアに持っています。あなたのコードの可読性と、あなたの(またはあなたの同僚の)脳にどれくらいの負荷をかけるかを考慮する必要があります。

私は、SRPは推奨でありルールではないと言います。 SongPlayerが何が起こっているのか分かりにくい場合は、ただSRPを落としてSong#playに固執してください

いつでもリファクタリングすることができます。私はSong#playで始まり、Songが演奏に関連したコードで肥大化し始めたら、その物をSongPlayerクラスにリファクタリングしたいと思います。

0

あなたは歌に歌手を渡す必要があります。これは本当のOOP方法です。なぜなら、あなたは懸念を分けているから、それは良いことです。

あなたの例としては、「あなたは教えてください、質問しないでください」。だから、歌はいつも歌手に次のように宣伝するように言っている:

class Song 
    ... 
    def play 
    # So that, singer will use the template and add the details 
    puts @singer.to_s("Belting it out by #{name}, winner of #{grammy_count} grammies!") 
    end 
end 

これは私の2セントです。