2011-11-24 22 views
5

Wydaje mi się, że mam do czynienia z kilkoma problemami z projektowaniem i nigdy nie wiem, co jest właściwe. Z jednej strony często słyszę, że powinienem ograniczyć łączność i trzymać się jednej odpowiedzialności, ale kiedy to robię, często trudno jest uzyskać do uzyskać informacje do części programu, gdy jest to potrzebne. Dla przykładZasada najlepszych zasad

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

Następnie powinna być piosenka:

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

lub

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

Im później ma mniej sprzęgło, więc zgodnie z zasadami powinien go używać. Ale jeśli później odkryję coś w Song, muszę wiedzieć więcej o piosenkarce , jestem w złym stylu. na przykład

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

byłbym w kropce gdybym użył klasy Song, później zamiast dawnej. Ale podejrzewam, że ktoś przypominają mi SRP, zasada jednej odpowiedzialności i sugerują zamiast:

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 

I tak, myślę, że to ma sens, ponieważ inny śpiewak może zrobić pokrywę z ktoś inny jest piosenka, prawda? Ale czy naprawdę byłaby to dokładnie ta sama piosenka ? W większości przypadków nigdy nie jest to ta sama "piosenka", więc nigdy nie mam takiego scenariusza, jak . Czy zatem SRP warty dodatkowych zajęć, które przynosi do kodu ?

Czasami myślę, że wiele zasad OOP, SOLIDNYCH lub innych, powstało z powodu ograniczeń języka Java i nie pasuje do Rubiego.

Odpowiedz

6

Sprzęgło powinno być trzymane przeciwko innej koncepcji, cohesion. Chcesz osiągnąć równowagę między tymi dwoma, a nie tylko doprowadzić jeden z nich do skrajności. W twoim przykładzie zdaje się, że singer_name należy do Singer, więc aby zachować spójność, należy przekazać obiekt Singer do Song, a nie name.

Mówiąc ogólniej, należy pamiętać, że takie zasady są jedynie wytycznymi. Zawsze musisz stosować zdrowy rozsądek i swoje unikalne zrozumienie domeny problemu. Rzadko istnieje wyraźny przypadek - może się nawet zmienić wraz ze wzrostem aplikacji lub lepszym zrozumieniem domeny.

2

Programy obiektowe powinny modelować rzeczywiste obiekty. W życiu piosenka należy do piosenkarza, a nie do imienia piosenkarki, aw swoich programach należy ją tak modelować.

Jak już wspomniano w @troelskn istnieje pojęcie sprzężenia, ale istnieje również koncepcja spójności ... Zasady są świetne, ale zdrowy rozsądek powinien mieć pierwszeństwo.

2

Ruby ma programista szczęścia w swojej istocie.Powinieneś wziąć pod uwagę czytelność swojego kodu i to, jak bardzo obciąża on mózg (lub kolegę), szczególnie gdy musisz przejść i zrozumieć go ponownie po dłuższej przerwie.

Powiedziałbym, że SRP powinno być traktowane jako zalecenie, a nie reguła. Jeśli SongPlayer utrudnia zrozumienie, co się dzieje, po prostu upuść SRP i pozostań przy Song#play, jeśli to ułatwi, za wszelką cenę, idź z nim.

Pamiętajcie, że zawsze możecie refaktoryzować. Zacznę od Song#play, a jeśli Song zacznie napełniać się związanym z grą kodem, wtedy będę refactorować te rzeczy do klasy SongPlayer.

0

Powinieneś przekazać Singera piosence, to jest prawdziwa droga OOP. Ponieważ rozdzielacie obawy, to dobrze.

Co do Twojego przykładu, powinieneś powiedzieć, nie pytaj. Tak więc, piosenka zawsze mówi Piosenkarzowi, żeby się tak zareklamował:

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 

To są moje dwa centy.

Powiązane problemy