Lo hice hoy.Traducido a los vehículos que se vería así:
class Vehicle
VEHICLES = {}
def self.register_vehicle name
VEHICLES[name] = self
end
def self.vehicle_from_name name
VEHICLES[name].new
end
end
class Bike < Vehicle
register_vehicle 'mountain bike'
end
class Car < Vehicle
register_vehicle 'ferrari'
end
me gusta que las etiquetas de las clases se mantienen con las mismas clases, en lugar de tener información sobre una subclase almacenado con la superclase. El constructor no se llama new
, pero no veo ningún beneficio en el uso de ese nombre en particular, y haría las cosas más complicadas.
> Vehicle.vehicle_from_name 'ferrari'
=> #<Car:0x7f5780840448>
> Vehicle.vehicle_from_name 'mountain bike'
=> #<Bike:0x7f5780839198>
Tenga en cuenta que algo necesita para asegurarse de que estas subclases se cargan antes de ejecutar vehicle_from_name (presumiblemente estas tres clases estarían en diferentes archivos de origen), de lo contrario la superclase no tendrá forma de saber qué subclases existe, es decir, no puede depender de la autocarga para extraer esas clases cuando ejecuta el constructor.
Lo resolví colocando todas las subclases en, p. Ej. un subdirectorio vehicles
y añadiendo esto al final de vehicle.rb
:
require 'require_all'
require_rel 'vehicles'
Utiliza la require_all
joya (que se encuentra en https://rubygems.org/gems/require_all y https://github.com/jarmo/require_all)
Podría utilizar mixins? Lo que quiero decir es que tienes que tener clases para Bike y Car? ¿Podrías tener una mezcla de Bike y Car que se podría incluir o extender en el objeto creado en el constructor? –
Hmm, supongo que en principio, aunque es más un hack, el concepto correcto de OO es que el objeto resultante es "una bicicleta o un automóvil, no se comporta como una bicicleta o un automóvil". – Peter
¿Cómo sabe su código qué tipo de objeto se requiere? ¿Hay algún tipo de tabla de búsqueda involucrada? –