lundi 8 novembre 2021

Prepare the environment of object A using object B following good programming practices

I would like to prepare a code consistent with good programming practices, which will initialize an object A that requires an additional action from object B and clean up after object A is not used anymore.

Let's say I've SensorBench class, which is class helping to maintain a couple of sensors.

class SensorBench:
    def __init__(
        self,
        sensor_1_address: int,
        sensor_2_address: int,
    ):
        self.sensor_1 = Sensor(sensor_1_address)
        self.sensor_2.Sensor(sensor_2_address)
    
    def add_laser_sensor(sensor_address):
        """
        This sensor is dangerous for human eye, therefore needs to be manually activated.
        Use LaserSensorActivator for that. 
        """
        self.additional_sensor = self.Sensor(sensor_address)
        return self

    def add_laser_sensor_activator():
        self.laser_sensor_activator = LaserSensorActivator()
        return self

And a class, which helps to initialize those sensors. Please notice, that I need to activate laser sensor via another object.

class SensorBenchesCreator:
    @staticmethod
    def get_basic_sensor_bench() -> SensorBench:
        return SensorBench(
                sensor_1_address=0x01,
                sensor_2_address=0x02,
            )

    @staticmethod
    def get_sensor_bench_with_laser_sensor() -> SensorBench:
         sensor_bench = SensorBench(
                sensor_1_address=0x01,
                sensor_2_address=0x02,
            )
            .add_laser_sensor_activator()
         sensor_bench.laser_sensor_activator.activate_sensor()
         sensor_bench.add_laser_sensor(0x03)  # Activate sensor before initialization. 
                                            # Otherwise exception will be raised.
        
         return sensor_bench

Now I've a fixture, which will take care about automatic deactivation of laser sensor. We don't want to damage someone's eye, so it's important to disable this sensor.

@pytest.fixture
def sensor_bench_fixture():
    sensor_bench = SensorBenchesCreator.get_sensor_bench_with_laser_sensor()

    yield sensor_bench

    sensor_bench.laser_sensor_activator.deactivate_sensor()

As you can see, activating/deactivating of this object is taking part in different classes, which seems to be code-smell. This may not seem like a big deal in this example, but in a project where I'm struggling with this problem it's become quite persistent and I'd like to move the control to one place. It is not that easy because I need to toggle a relay that is controlled by a completely different class.

Do you have any tip what can I do to activate and deactivate sensor from the same place? Either in pytest fixture or in get_sensor_bench_with_laser_sensor method.

Aucun commentaire:

Enregistrer un commentaire