5 ms·
I really enjoyed this writing! The only thing that I find weird is the description of the leaky abstractions for the pin interface in "traditional" OOP. I unde
by MauranKilom 6y ago
I really enjoyed this writing!
The only thing that I find weird is the description of the leaky abstractions for the pin interface in "traditional" OOP. I understand the general sentiment, but this particular case is a prime example where polymorphy expresses the exact same thing just as well (here in C++):
class Pin
{
public:
Pin(std::uint8_t pin) : _pin(pin) {}
virtual ~Pin() = default; // base class could also be made abstract here
private:
std::uint8_t _pin;
};
class ReadPin : public Pin
{
public:
ReadPin(std::uint8_t pin) : Pin(pin) {}
double read();
};
class WritePin : public Pin
{
public:
WritePin(std::uint8_t pin) : Pin(pin) {}
void write(double level);
};
You can then end up either with
ReadPin sensor_pin = gpio.getReadPin(SENSOR);
or, if you for some reason want to keep the chaining, nothing prevents you from having a
ReadPin sensor_pin = gpio.getPin(SENSOR).asReadPin();
Maybe it's just not the right kind of example, but I don't really understand how OOP's failure is that you can call write on a ReadPin. The author says:
> This kind of compromise happens often in the "kitchen sink" approach of OOP, where a child class might have access to inappropriate data or behaviour. Perhaps that data is relevant to a sibling class, but this is a sign of the abstraction leaking.
...which boils down to "if you violate the Liskov Substitution Principle, you are not using OOP correctly". I concede that this can and occasionally does happen in practice, but it's not like other languages are incapable of following the SOLID. It might just be easier to not do so.
- Jare 6y agoI'm improvising here, but if pins can be switched from read to write (but can only be in one of those at a time), then in Rust you should be able to use the borrow checker to provide additional guarantees. As long as a pin is borrowed by a ReadPin, you can't create a WritePin, and viceversa. As you say, you can use the same approach in C++, but this is one reason why the approach is extra interesting in Rust.