Eu estou projetando uma API que lida com diferentes tipos de veículos por exemplo, carros, ônibus e vans. Há um ponto final POST /vehicle
que terá um corpo definido.
{
'registration': 'str',
'date_of_purchase': 'datetime str',
'vehicle_type': 'car'
...
}
A primeira coisa que fazemos é carregar um objeto com base no VEHICLE_TYPE.
if body[vehicle_type] == 'car':
passed_in_vehicle = Car(body)
elif body['vehicle_type'] == 'bus':
passed_in_vehicle = Bus(body)
...
Dentro do programa de python, existem várias classes, incluindo:
- vehicles.py
- cars.py
- vans.py
- buses.py
O ponto de entrada da API vai para vehicles.py que faz alguma lógica e, em seguida, dependendo da rota vontade entrada para uma das outras classes para fazer lógica mais específico.
Cada classe tem o mesmo conjunto de métodos de base.
- update_vehicle_specs
- register_vehicle
No momento no fundo do vehicles.py tenho
if is_instance(passed_in_vehicle, Car):
carService = Cars()
carService.register_vehicle(passed_in_vehicle)
elif is_instance(passed_in_vehicle, Van):
vanService = Vans()
vanService.register_vehicle(passed_in_vehicle)
...
No entanto, isso não pode ser escalável. Qual é a solução correta para encaminhar a classes específicas com base em uma condição?
A forma como ele olha para mim, você pode melhorar o design um pouco. Uma vez que cada veículo 'sabe' onde é atendido, você provavelmente deve fazer em cada algo como
def __init__(self, ..., service):
super().__init__(self, ...)
...
...
service.register_vehicle(self)
este é proveniente da perspectiva de que "as unidades de carro para a garagem para se registrar", em vez de os "olhares garagem para carros novos".
Quando você inicializar um veículo, passá-lo sua classe manutenção, como em
new_car = Car(..., my_car_service)
Onde
my_car_service = Cars()
em algum lugar antes. Isto é, desde que assumimos cada carro novo precisa se registrar, e nós não faça um novo serviço para cada carro novo. Outra abordagem, é para a classe para conter (composição) o seu objeto de serviço do go get:
class Car:
service = Cars()
def __init__(...)
...
Car.service.register_vehicle(self)
por isso a classe contém o objeto de manutenção sempre, e todos os objetos inicializados compartilhar a mesma através de uma variável de classe. Eu realmente prefiro isso.
Primeira inicialização:
No que diz respeito à sua inicialização inicial do veículo, enquanto estiver usando locals
pode ser uma solução bacana para isso, pode ser um pouco mais tipo seguro para ter algo parecido com o que você tem. Em Python Eu gosto de usar o "Python interruptor dicionário" (TM) para coisas assim:
{'car': Car,
'bus': Bus,
...
'jet': Jet
}[body[vehicle_type]](body)