2011-11-24 10 views
5

Parece que me encuentro con un par de cuestiones de diseño mucho y nunca sé qué es realmente adecuado. Por un lado, a menudo escucho que debo limitar el acoplamiento y a la única responsabilidad, pero cuando lo hago a menudo me resulta difícil a obtener la información de una parte del programa cuando sea necesario. Para ejemplo,Principio de los mejores principios

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

Entonces debería ser Canción:

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

o

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

Este último, tiene menos de acoplamiento, lo que de acuerdo a los principios que deberían usarlo. Pero si más tarde descubro algo en Song, necesito saber más sobre el cantante , estoy en un mal camino. p.ej.

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

Estaría en un aprieto si hubiera utilizado la clase Song tarde en lugar de la antigua . Pero entonces sospecho que alguien me recordará de SRP, solo principio responsabilidad , y sugieren su lugar:

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 

Y sí, supongo que tiene sentido, ya que otro cantante podría hacer una cubierta de alguien más es canción, ¿verdad? Pero entonces, ¿sería realmente la misma canción exacta de ? En la mayoría de mis casos, nunca es la misma "canción", así que nunca tengo ese tipo de escenario . Entonces, ¿vale la SRP las clases adicionales que aporta al código ?

A veces pienso que muchos principios OOP, SÓLIDOS u otros, surgieron de las limitaciones de Java de , y no se aplican tan bien a Ruby.

Respuesta

6

El acoplamiento debe considerarse frente a otro concepto, cohesion. Desea lograr un equilibrio entre los dos, en lugar de simplemente llevar uno de ellos al extremo. En su ejemplo, singer_name parece pertenecer a Singer, por lo que para preservar la cohesión, debe pasar el objeto Singer al Song, en lugar del name.

Más en general, debe tener en cuenta que tales principios son meras líneas de guía. Siempre debe aplicar el sentido común y su comprensión única del dominio del problema. Rara vez hay un caso claro: incluso podría cambiar a medida que crezca su aplicación o cuando comprenda mejor el dominio.

2

Los programas orientados a objetos deben modelar objetos de la vida real. En la vida, una canción le pertenece a un cantante, no al nombre del cantante y en sus programas debe modelarlo de esta manera.

Como ya mencioné @troelskn existe el concepto de acoplamiento, pero también existe el concepto de cohesión ... Los principios son geniales, pero el sentido común debería tener prioridad.

2

Ruby tiene programador felicidad en su núcleo.Debería considerar la legibilidad de su código y cuánto fuerza su cerebro (o el de su colega), especialmente cuando tiene que atravesarlo y comprenderlo nuevamente después de una larga pausa.

Yo diría que SRP debería tomarse como una recomendación y no como una regla. Si SongPlayer hace que sea más difícil entender lo que está pasando, simplemente suelte SRP y quédese con Song#play, si eso lo hace más fácil, por supuesto, vaya con él.

Y recuerde, siempre puede refactorizar. Comenzaría con Song#play y si Song comienza a hincharse con el código relacionado con el juego, entonces lo refactorizaría a una clase SongPlayer.

0

Debería pasar Singer to Song, esta es la verdadera manera OOP. Porque, estás separando preocupaciones, eso está bien.

En cuanto a su ejemplo, 'debe decir, no pregunte'. Entonces, Song siempre le estará diciendo a Singer que se anuncie así:

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 

Este es mi dos centavos.

Cuestiones relacionadas