W tej chwili mam dwie klasy: ST7789V jako driver (funkcje init, write, ...), i dziedziczącą po niej prywatnie klasę Display
A co, gdybyś teraz miał napisać sterownik dla SSD1963 i chciał mieć funkcję, która przyjmie po prostu Display? :-)
Powinieneś to zaprojektować na odwrót, czyli mieć klasę Display z abstrakcyjną metodą drawPixel(x, y), a następie klasę ST7789V, która dziedziczy po Display i realizuje tę metodę.
Taki design nadal byłby zły, choć nieco lepszy od Twojego aktualnego.
IMHO najsensowniej rozplanować to kompozycją (w pseudokodzie):
Kopiuj
interface LcdDriver {
void drawPixel(uint x, uint y);
}
class ST7789V
implements Driver {
/* ... */
}
class SSD1963
implements Driver {
/* ... */
}
class Display {
Display(LcdDriver driver) {
this->driver = driver;
}
void drawPixel(uint x, uint y) {
this->driver->drawPixel(x, y);
}
void drawRectangle(uint x, uint y, uint width, uint height) {
for (...) {
/* ... */
}
}
}
// i potem gdziekolwiek:
Display createDisplay() {
return new Display(
new DowolnySterownik()
);
}
void drawSomething(Display display) {
display->drawText(...);
display->drawRectangle(...);
}