Hier ist mein Problem: Ich möchte Eingaben von verschiedenen HID-Geräten wie einem Gamepad, einem Rennsport, einem Joystick usw. lesen. So ziemlich jeder Gamecontroller. Das Problem ist, dass sie alle unterschiedliche Eingänge haben.
Das Gamepad verfügt über Tasten, Schalter und Sticks, während der Rennsport möglicherweise einen Schalthebel hat. Ich habe es geschafft, all diese verschiedenen Komponenten in nur 3 zu abstrahieren, anstatt eine Basisklasse mit allen möglichen Kombinationen zu haben:
abstract class Device
{
public Buttons Buttons;
public Axes Axes;
public Switches Switches;
public GearSticks GearSticks;
//many more
}
Ich kann jetzt haben:
abstract class Device
{
public Buttons Buttons; //on or off
public Axes Axes; //range [-100%:100%]
public Switches Switches; //multiple states
}
Anfangs war ich damit zufrieden, da es alle möglichen Arten von Eingaben abzudecken schien und meine Klasse geschlossen bleiben kann, während sie über alle konkreten Implementierungen erweitert werden kann, da alles auf nur drei Arten von Eingaben abstrahiert werden kann.
ABER dann überlege ich mir was, wenn ich nur das Unvermeidliche verzögere? Was ist, wenn ich eines Tages meiner Device
Klasse ein weiteres Feld hinzufügen muss ? Es unterstützt so etwas wie einen Trackball nicht!
Gibt es eine Möglichkeit, diese Klasse zukunftssicher zu machen? So wie ich es sehe, würde ich am Ende so etwas haben:
public Device1 : Device
{
//buttons
//trackball
}
public Device2 : Device
{
//Switch
//Axis
}
public Device3 : Device
{
//trackball
//switch
}
Und ich müsste meiner Basisklasse jedes Mal Eigenschaften hinzufügen, wenn etwas Neues implementiert werden muss.
quelle
parameter1=value1¶meter2=value2
usw.Antworten:
Ich bin mir ziemlich sicher, dass dies durch die Einführung eines abstrakten Konzepts
InputChannel
und von Geräten mit einer konfigurierbaren Liste von Eingangskanälen erreicht werden kann. Ein Eingangskanal hat einen Namen, einen Typ, möglicherweise einige Metadaten, und er muss in der Lage sein, einen "Status" zu erzeugen, der zu diesem Typ passt. Möglicherweise gibt es vordefinierte Kanäle wie eine Schaltfläche, eine Axt oder einen Schalter oder einen neuen Kanal, den Sie derzeit nicht kennen (der jedoch später durch Einführung einer neuenInputChannel
untergeordneten Klasse hinzugefügt werden kann ).Auf diese Weise wird ein Gerät zu einer Art Metamodell, und Sie benötigen auch eine Möglichkeit, die Gerätezustände zu verwalten, die der Liste der Eingangskanäle des Geräts entsprechen müssen.
Diese Art von generischem Ansatz birgt jedoch ein gewisses Risiko für Überentwicklung, auch als Inner-Platform-Effekt bekannt . Beispielsweise ist es möglicherweise nicht einfach, einem solchen generischen Gerät bestimmte Funktionen oder bestimmte Ereignisse oder Interaktionen zwischen verschiedenen Eingangskanälen hinzuzufügen. Es kann für einen Benutzer Ihrer generischen Gerätebibliothek auch schwieriger sein, diese zu verwenden und zu verstehen.
Beachten Sie, dass es nicht immer vorteilhaft ist, eine möglichst abstrakte Lösung zu erstellen. Das Ändern von Anforderungen an die Hardware erfordert in der Regel einen wesentlich höheren Aufwand für die Implementierung in der Hardware selbst als in der entsprechenden Software. Daher ist es häufig besser, sich an eine spezifischere Lösung in der Software zu halten und die Software bei Bedarf zu ändern.
quelle
InputChannel
Dose funktioniert, alles was ich tun muss, ist ihren Status zu aktualisieren und eine zu erhöhenonChangedEvent
. Aber Sie haben vielleicht Recht mit der Überentwicklung ... Ich werde dies berücksichtigen. Denken Sie, dass es akzeptabel ist, ab und zu ein weiteres Feld zu einer Klasse hinzuzufügen?Die Idee hinter dem Open-Closed-Prinzip ist, dass es weniger wahrscheinlich ist, dass vorhandene Funktionen beschädigt werden, wenn Sie neue Funktionen durch Vererbung implementieren, anstatt eine vorhandene Klasse zu ändern. Und Sie können dies tun, indem Sie von Ihrem Versteck erben. In einem Jahr und ein paar Monaten können Sie ein Hid2020 erstellen, das von Hid erbt und Unterstützung für den Trackball bietet, der im vierten Quartal 2019 erfunden wird. Nach der Erfindung und Popularisierung des Quetschdetektors im Jahr 2023 können Sie eine Hid2024-Klasse erstellen, die stammt von Hid2019 ab.
Das wäre der defensive Ansatz. Aus sauberer Sicht wäre es aber auch etwas schlampig. In Ihrem Fall würde ich keinen Schlaf verlieren, wenn ich gegen O verstoße, und einfach die Basisklasse ändern, wenn sich die Welt um Sie herum ändert. Es scheint nicht so, als würde die Implementierung für Trackball oder eine andere neue Art der Steuerung die Art und Weise beeinflussen, wie Sie jetzt mit Tastendrücken oder Statusänderungen umgehen.
quelle