私は、例えば、自動車、バス、バンのための車の異なる種類を扱うAPIを設計しています。エンドポイントがあるPOST /vehicle
定義されたボディがかかります。
{
'registration': 'str',
'date_of_purchase': 'datetime str',
'vehicle_type': 'car'
...
}
私たちが行う最初のことは、車両の種類に基づいてオブジェクトをロードしています。
if body[vehicle_type] == 'car':
passed_in_vehicle = Car(body)
elif body['vehicle_type'] == 'bus':
passed_in_vehicle = Bus(body)
...
Pythonプログラムの中に含めて複数のクラスがあります。
- vehicles.py
- cars.py
- vans.py
- buses.py
APIのエントリポイントは、いくつかのロジックを行い、その後、より多くの固有のロジックを実行するために、他のクラスの1つに入力意志ルート、それに応じて、vehicles.pyに行きます。
各クラスは、基本メソッドの同じセットを持っています。
- update_vehicle_specs
- register_vehicle
私が持っているvehicles.pyの下で瞬間
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)
...
しかし、これは、スケーラブルにすることはできません。条件に基づいて、特定のクラスへの経路への正しい解決策は何ですか?
それは私には見えるように、あなたは少しの設計向上させることができます。各車両は「知っている」ので、それがサービスされた場合、あなたはおそらくのような各何かに行う必要があります
def __init__(self, ..., service):
super().__init__(self, ...)
...
...
service.register_vehicle(self)
これはむしろ、「新しい車のためのガレージルックス」よりも「登録するにはガレージに車のドライブ」という視点から来ています。
あなたが車を初期化すると、のように、そのサービスを提供するクラスを渡します
new_car = Car(..., my_car_service)
どこ
my_car_service = Cars()
前にどこか。私たちはそれぞれの新しい車を登録する必要があり、私たちはそれぞれの新しい車のための新しいサービスを作成していないと仮定ので、これはです。別のアプローチは、GETの外出先から(組成)そのサービスオブジェクトを格納するクラスです。
class Car:
service = Cars()
def __init__(...)
...
Car.service.register_vehicle(self)
そのクラスは、常にサービスするオブジェクトが含まれており、すべての初期化オブジェクトは、クラス変数を介して同じものを共有しています。私は実際にこれを好みます。
最初の初期化:
使用中の車両のあなたの最初の初期化に関しては、locals
そのために気の利いたソリューションであるかもしれない、それは少しより多くのタイプセーフあなたが持っているもののようなものを持っているかもしれません。Pythonの私にはそのようなものは、「Pythonのスイッチ辞典」(TM)を使用したいです:
{'car': Car,
'bus': Bus,
...
'jet': Jet
}[body[vehicle_type]](body)