找到代码重复的正确模式

Find the right pattern for code duplication

我有一个汽车服务正在使用汽车 api 来处理汽车。问题是我在服务的每个方法中都使用 get_driver_car 来获取汽车对象,最后我使用 update_car 方法来保存数据。从我的角度来看,这两种方法似乎可以从另一种方法使用,但我不知道如何重构这段代码。我很高兴听到所有建议

class CarService(object):
    def __init__(self):
        self.api = CarApiService()

    def add_branding(self, car_id: str):
        car = self.api.get_driver_car(json.dumps({'car_id': car_id}))['car']
        if 'sticker' not in car['amenities']:
            car['amenities'].append('sticker')

        if 'lightbox' not in car['amenities']:
            car['amenities'].append('lightbox')

        return self.api.update_car({'car_id': car_id, 'data': json.dumps(self.create_car_request(car))})

    def remove_branding(self, car_id: str):
        car = self.api.get_driver_car(json.dumps({'car_id': car_id}))['car']
        
        if 'sticker' in car['amenities']:
            del car['amenities'][car['amenities'].index('sticker')]

        if 'lightbox' in car['amenities']:
            del car['amenities'][car['amenities'].index('lightbox')]

        return self.api.update_car({'car_id': car_id, 'data': json.dumps(self.create_car_request(car))})

    def add_booster(self, car_id:str):
        car = self.api.get_driver_car(json.dumps({'car_id': car_id}))['car']

        if car['booster_count'] == 0:
            car['booster_count'] = 1
        else:
            return None

        return self.api.update_car({'car_id': car_id, 'data': json.dumps(self.create_car_request(car))})

    def remove_booster(self, car_id: str):
        car = self.api.get_driver_car(json.dumps({'car_id': car_id}))['car']

        if car['booster_count'] == 1:
            car['booster_count'] = 0
        else:
            return None

        return self.api.update_car({'car_id': car_id, 'data': json.dumps(self.create_car_request(car))})
    def create_car_request(self, car: dict) -> dict:
        del car['is_readonly']
        del car['created_date']

        return car

优化此类内容的最基本步骤是为重复逻辑创建辅助方法。

我们可以替换一行复杂的代码:

return self.api.update_car({'car_id': car_id, 'data': json.dumps(self.create_car_request(car))})

有一个简单的:

return self._update_helper(car_id, car)

通过实施内部辅助方法:

def _update_helper(self, car_id: str, car: dict):
    return self.api.update_car({'car_id': car_id, 'data': json.dumps(self.create_car_request(car))})

您所有的重复方法共享相同的结构:

  1. 从 API 访问汽车。
  2. 对汽车进行一些改装。
  3. 将改装车送回API。

差异仅存在于步骤 #2 中。您应该能够创建某种包装器或 decorator 来进行步骤 #2 修改并将其变成一个完整的函数。

不幸的是,我没有在 Python 中编写代码,所以我不确定这里的语法。

def _create_car_modifier(self, func):
    def inner(self, car_id: str):
        car = self.api.get_driver_car(json.dumps({'car_id': car_id}))['car']
        if func(car) is None:
            return
        else
            return self.api.update_car({'car_id': car_id, 'data': json.dumps(self.create_car_request(car))})
    return inner