最佳原则原则

Ask*_*ker 5 ruby oop

我似乎遇到了很多设计问题,我从来不知道什么是真正合适的.一方面,我经常听到我应该限制耦合并坚持单一责任,但是当我这样做时,我经常发现在需要时很难将信息提供给程序的一部分.例如,

class Singer
  def initialize(name)
    @name = name
  end
  attr :name
end
Run Code Online (Sandbox Code Playgroud)

宋应该是:

class Song
  def new(singer)
    @singer = singer
  end
end
Run Code Online (Sandbox Code Playgroud)

要么

class Song
  def new(singer_name)
    @singer_name = singer_name
  end
end
Run Code Online (Sandbox Code Playgroud)

后者的耦合较少,所以根据原则我应该使用它.但如果我后来发现宋某需要了解更多有关歌手的事情,那我就是一个糟糕的方式.例如

 class Song
   ...
   def play
     puts "Belting it out by #{@singer.name}, winner of
     #{@singer.grammy_count} grammies!"
   end
 end
Run Code Online (Sandbox Code Playgroud)

如果我使用了后来的Song类而不是前者,我会解决这个问题.但后来我怀疑有人会提醒我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
Run Code Online (Sandbox Code Playgroud)

是的,我想这是有道理的,因为另一个歌手可能会掩盖别人的歌,对吗?但那么,它真的会是完全相同的歌吗?在我的大多数情况下,它永远不会是相同的"歌曲"所以我从来没有这种情况.那么SRP值得为代码带来额外的类吗?

我有时认为许多OOP原则(SOLID或其他原因)都会产生Java的局限性,并且不适用于Ruby.

tro*_*skn 6

耦合应该与另一个概念,凝聚力相抵触.你想在两者之间取得平衡,而不是仅仅将其中一个推向极致.在你的例子中,singer_name似乎属于Singer,所以为了保持凝聚力,你应该将Singer对象传递给Song,而不是name.

更一般地说,您需要记住,这些原则仅仅是指导原则.您始终必须运用常识和对问题域的独特理解.很少有明显的案例 - 甚至可能随着您的应用程序的增长或您更好地理解域名而改变.