Dies ist eine ziemlich vage Frage, aber ich habe nie das Gefühl, dass sie beim Lesen über das richtige Design zufriedenstellend beantwortet wurde.
Wenn Sie etwas über objektorientierte Programmierung, Abstraktion, Ausklammern usw. lernen, ist der heilige Gral des Designs - und der Grund, warum immer behauptet wird, dass Sie die fraglichen Entwicklungstechniken verwenden - im Allgemeinen, dass Ihr Programm dadurch "einfach zu ändern" wird. , "wartbar", "flexibel" oder eines der Synonyme, die verwendet werden, um ein solches produktiv klingendes Konzept auszudrücken. Indem Sie ivars als privat markieren, Code in viele kleine, in sich geschlossene Methoden aufteilen und die Schnittstellen allgemein halten, erhalten Sie angeblich die Möglichkeit, Ihr Programm mit absoluter Leichtigkeit und Anmut zu ändern.
Bei relativ kleinen Änderungen hat dies bei mir gut funktioniert. Änderungen an internen Datenstrukturen, die von einer Klasse zur Leistungssteigerung verwendet werden, waren nie eine große Schwierigkeit, und auch Änderungen an der Benutzeroberfläche, unabhängig von der API, wie die Neugestaltung eines Texteingabesystems oder die Überarbeitung der Grafiken für ein Gameplay-Element .
Alle diese Änderungen scheinen in sich geschlossen zu sein. Keine von ihnen beinhaltet Änderungen am Verhalten oder Design der Komponente Ihres Programms, die geändert wird, soweit es den externen Code betrifft. Unabhängig davon, ob Sie prozedural oder in einem OO-Stil mit großen oder kleinen Funktionen schreiben, können Sie diese Änderungen leicht vornehmen, selbst wenn Sie nur ein mäßig gutes Design haben.
Wenn jedoch die Änderungen groß und haarig werden - dh Änderungen an der API -, kommt keines meiner wertvollen "Muster" jemals zur Rettung. Die große Veränderung bleibt groß, der betroffene Code bleibt betroffen, und viele Stunden Bug-Spawning-Arbeit liegen vor mir.
Meine Frage lautet also: Wie groß ist die Veränderung, die das richtige Design für möglich hält? Gibt es eine weitere Designtechnik, die mir entweder unbekannt ist oder die ich nicht implementiert habe, die eine klebrig klingende Modifikation wirklich einfach macht, oder ist dieses Versprechen (das ich von so vielen verschiedenen Paradigmen gehört habe) nur eine nette Idee? völlig getrennt von den unveränderlichen Wahrheiten der Softwareentwicklung? Gibt es ein "Änderungswerkzeug", das ich meinem Werkzeuggürtel hinzufügen kann?
Das Problem, mit dem ich konfrontiert bin und das mich zu den Foren geführt hat, ist das folgende: Ich habe an der Implementierung einer interpretierten Programmiersprache gearbeitet (implementiert in D, aber das ist nicht relevant), und ich habe entschieden, dass die Argumente meiner Abschlüsse sein sollten eher schlüsselwortbasiert als positionell, wie sie derzeit sind. Dies erfordert das Ändern des gesamten vorhandenen Codes, der anonyme Funktionen aufruft, was zum Glück eher klein ist, da ich mich noch in einem frühen Stadium der Entwicklung meiner Sprache befinde (<2000 Zeilen), aber enorm wäre, wenn ich diese Entscheidung zu einem späteren Zeitpunkt getroffen hätte. Gibt es in einer solchen Situation eine Möglichkeit, diese Modifikation durch richtige Voraussicht im Design zu vereinfachen, oder sind bestimmte (die meisten) Änderungen an sich weitreichend? Ich bin gespannt, ob dies in irgendeiner Weise ein Versagen meiner eigenen Designfähigkeiten ist - wenn ja, ich '
Um klar zu sein, bin ich in keiner Weise skeptisch gegenüber OOP oder einem der anderen üblicherweise verwendeten Muster. Für mich liegen ihre Tugenden jedoch eher im ursprünglichen Schreiben als in der Aufrechterhaltung von Codebasen. Durch Vererbung können Sie sich wiederholende Muster gut abstrahieren, durch Polymorphismus können Sie Code nach vom Menschen verstandenen Funktionen (welche Klasse) und nicht nach maschinenverstandenen Effekten (welcher Zweig der switch
Anweisung) trennen , und kleine, in sich geschlossene Funktionen ermöglichen dies Schreiben Sie in einem sehr angenehmen "Bottom-up" -Stil. Ich bin jedoch skeptisch gegenüber ihren Flexibilitätsansprüchen.
foo metarg1: bar metarg2: baz
wie foo.metarg1_metarg2_(bar, baz)
. Meine Sprache nimmt jedoch eine größere Änderung vor, nämlich listbasierte Parameter zu wörterbuchbasierten Parametern, die sich auf die Laufzeit, aber nicht auf den Parser auswirken. Aufgrund bestimmter Eigenschaften meiner Sprache werde ich im Moment nicht darauf eingehen. Da es keine eindeutige Zuordnung zwischen ungeordneten Schlüsselwörtern und Positionsargumenten gibt, ist die Laufzeit das Hauptproblem.