2011-11-24 15 views
5

Mi sembra di imbattersi in un paio di problemi di progettazione molto e non so mai cosa sia veramente corretto. Da una parte sento spesso che dovrei limitare l'accoppiamento e attenersi a una singola responsabilità, ma quando lo faccio spesso trovo difficile a ottenere le informazioni a parte del programma quando è necessario. Ad esempio ,Principio dei migliori principi

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

Poi dovrebbe essere canzone:

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

o

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

Più tardi ha meno di accoppiamento, a tal fine i principi che dovrebbero usarlo. Ma se in seguito scoprirò qualcosa in Song ha bisogno di sapere di più sul cantante , sono in un brutto modo. per esempio.

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

Sarei in una correzione se avessi usato la classe Song in seguito al posto del ex. Ma poi ho il sospetto che qualcuno mi avrebbe ricordato di SRP, unico principio responsabilità , e suggeriscono invece:

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 

E sì, immagino che abbia un senso, dal momento che un altro cantante potrebbe fare una cover di qualcun altro è canzone, giusto? Ma allora, sarebbe davvero la stessa canzone ? Nella maggior parte dei casi non è mai la stessa "canzone", quindi non ho mai lo tipo di scenario. Quindi lo SRP vale le classi extra che aggiunge al codice ?

A volte penso che molti principi OOP, SOLID o altrimenti, sono sorti a limitazioni di Java e non si applicano molto bene a Ruby.

risposta

6

L'accoppiamento deve essere tenuto contro un altro concetto, cohesion. Tu vuoi trovare un equilibrio tra i due, piuttosto che portarne uno solo all'estremo. Nell'esempio, singer_name sembra appartenere a Singer, quindi per preservare la coesione, è necessario passare l'oggetto Singer a Song anziché a name.

Più in generale, è necessario tenere presente che tali principi sono solo linee guida. Devi sempre applicare il buon senso e la tua comprensione unica del dominio del problema. Raramente c'è un caso ben definito: potrebbe persino cambiare quando la domanda cresce o se si capisce meglio il dominio.

2

I programmi orientati agli oggetti dovrebbero modellare gli oggetti della vita reale. Nella vita una canzone appartiene a un cantante, non al nome del cantante e nei tuoi programmi dovresti modellarlo in questo modo.

Come già accennato da @troelskn, esiste il concetto di accoppiamento, ma esiste anche il concetto di coesione ... I principi sono grandi, ma il buon senso dovrebbe avere la precedenza.

2

Ruby ha programmatore felicità al suo interno.Dovresti considerare la leggibilità del tuo codice e quanto metta a dura prova il tuo cervello (o del tuo collega), specialmente quando devi attraversarlo e capirlo di nuovo dopo una lunga pausa.

Direi che lo SRP dovrebbe essere considerato come una raccomandazione e non come una regola. Se SongPlayer rende più difficile capire cosa sta succedendo, basta rilasciare SRP e attaccare con Song#play, se rende più facile, con tutti i mezzi, andare con esso.

E ricorda, puoi sempre refactoring. Vorrei iniziare con Song#play e se Song inizia a essere gonfiato con il codice relativo al gioco, quindi avrei refactor che roba in una classe SongPlayer.

0

Si dovrebbe passare Singer a Song, questo è vero modo OOP. Perché, stai separando le preoccupazioni, va bene.

Come per il tuo esempio, "dovresti dire, non chiedere". Così, Song dice sempre a Singer di farsi pubblicità in questo modo:

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 

Questo è il mio due centesimi.

Problemi correlati