Wahrscheinlich habe ich wie viele andere Probleme mit Designproblemen, bei denen es beispielsweise ein Designmuster / einen Designansatz gibt, das intuitiv zu dem Problem zu passen scheint und die gewünschten Vorteile bietet. Sehr oft gibt es einige Einschränkungen, die es schwierig machen, das Muster / den Ansatz ohne irgendeine Art von Arbeit zu implementieren, die dann den Nutzen des Musters / Ansatzes negiert. Ich kann sehr leicht durch viele Muster / Ansätze iterieren, da vorhersehbar fast alle in realen Situationen, in denen es einfach keine einfache Lösung gibt, einige sehr bedeutende Einschränkungen aufweisen.
Beispiel:
Ich werde Ihnen ein hypothetisches Beispiel geben, das lose auf einem realen basiert, dem ich kürzlich begegnet bin. Angenommen, ich möchte Komposition über Vererbung verwenden, da Vererbungshierarchien in der Vergangenheit die Skalierbarkeit des Codes beeinträchtigt haben. Ich könnte den Code umgestalten, aber dann feststellen, dass es einige Kontexte gibt, in denen die Oberklasse / Basisklasse einfach die Funktionalität der Unterklasse aufrufen muss, obwohl versucht wird, dies zu vermeiden.
Der nächstbeste Ansatz scheint darin zu bestehen, ein Muster aus einem halben Delegierten / Beobachter und einem halben Kompositionsmuster zu implementieren, damit die Oberklasse das Verhalten delegieren kann oder damit die Unterklasse Ereignisse der Oberklasse beobachten kann. Dann ist die Klasse weniger skalierbar und wartbar, da unklar ist, wie sie erweitert werden soll. Außerdem ist es schwierig, vorhandene Listener / Delegaten zu erweitern. Auch Informationen sind nicht gut versteckt, da man die Implementierung kennen muss, um zu sehen, wie die Oberklasse erweitert werden kann (es sei denn, Sie verwenden Kommentare sehr häufig).
Danach könnte ich mich dafür entscheiden, einfach nur Beobachter oder Delegierte vollständig einzusetzen, um den Nachteilen zu entkommen, die mit einer starken Verwechslung der Ansätze verbunden sind. Dies bringt jedoch seine eigenen Probleme mit sich. Zum Beispiel könnte ich feststellen, dass ich für eine zunehmende Anzahl von Verhaltensweisen Beobachter oder Delegierte benötige, bis ich für praktisch jedes Verhalten Beobachter / Delegierte benötige. Eine Option könnte darin bestehen, nur einen großen Listener / Delegaten für das gesamte Verhalten zu haben, aber dann hat die implementierende Klasse viele leere Methoden usw.
Dann könnte ich einen anderen Ansatz versuchen, aber es gibt genauso viele Probleme damit. Dann der nächste und der nach etc.
Dieser iterative Prozess wird sehr schwierig, wenn jeder Ansatz so viele Probleme zu haben scheint wie jeder andere und zu einer Art Lähmung der Entwurfsentscheidung führt . Es ist auch schwierig zu akzeptieren, dass der Code gleichermaßen problematisch wird, unabhängig davon, welches Entwurfsmuster oder welcher Ansatz verwendet wird. Wenn ich in dieser Situation lande, bedeutet das, dass das Problem selbst überdacht werden muss? Was machen andere, wenn sie auf diese Situation stoßen?
Bearbeiten: Es scheint eine Reihe von Interpretationen der Frage zu geben, die ich klären möchte:
- Ich habe OOP vollständig aus der Frage herausgenommen, weil sich herausstellt, dass es nicht spezifisch für OOP ist, und es zu leicht ist, einige der Kommentare, die ich im Vorbeigehen über OOP gemacht habe, falsch zu interpretieren.
- Einige haben behauptet, ich sollte einen iterativen Ansatz wählen und verschiedene Muster ausprobieren, oder ich sollte ein Muster verwerfen, wenn es nicht mehr funktioniert. Dies ist der Prozess, auf den ich mich überhaupt beziehen wollte. Ich dachte, das wäre aus dem Beispiel klar, aber ich hätte es klarer machen können, also habe ich die Frage bearbeitet, um dies zu tun.