static abstract Alternative?
-
Ahoi ...
ich habe eine abstrakte Klasse, die eine Schnittstelle für Datenquellen definiert. Nun möchte ich, dass konkrete Datenquellenimplementierungen eine Methode bereitstellen, die eine Erzeugung (neu anlegen) der konkreten Datenquelle implementieren. Optimal wäre hier, wenn ich diese Methode in der Basisklasse als static abstract deklarieren könnte, aber das geht natürlich nicht.
Es gibt einen Manager, der zu Beginn alle Implementierungen feststellt und ggf. Datenquellen anlegen muss. Dazu brauch der Manager eine gescheite Schnittstelle. Atm fällt mir einfach nichts ein, daher würd ich mich über ein paar Vorschläge freuen. Danke im Voraus ...
-
Singleton-Pattern?
-
Mhmm wie kommst du auf ein Singleton? Ich dachte, aus meiner Erklärung geht hervor, dass ich mit Erzeugung nicht die Instanziierung der Zugriffsklasse sondern das Anlegen der Datenquelle selbst (Datenbank, Datei, TCP-Verbindung, etc.) meine.
wyfrn schrieb:
Optimal wäre hier, wenn ich diese Methode in der Basisklasse als static abstract deklarieren könnte,
Damit meine ich, dass ich die Signatur der Methode gerne in der Basisklasse vorgeben würde und jede konkrete Zugriffsklasse eine eigene Implementierung dieser bereitstellt. Sozusagen als virtuelle static Methode. Das es so nicht geht, ist klar.
-
Was spricht denn dagegen, einfach eine normale abstract Methode anzubieten die dann alle Klassen überschreiben? Wobei ich ein abstract hier nicht gut finde, denn dann bist du nicht gezwungen die Methode zu überschreiben. Wäre ein Interface nicht angebrachter, wenn du das implementierst, ist "Zwang-Faktor" zwar nicht höher, aber du siehst wenigstens direkt was du noch alles implementieren musst und bekommst eine NotImplemented Exception bei nicht Implementierung.
-
Firefighter schrieb:
Was spricht denn dagegen, einfach eine normale abstract Methode anzubieten die dann alle Klassen überschreiben?
Ja das könnte man natürlich machen, nur ist es teilweise unmöglich, eine Zugriffsklasse zu instanziieren wenn dazu keine passende Datenquelle existiert.
Ein Großteil des Codes stammt nicht von mir und ich kann/darf daran keine Änderungen vornehmen. Die Erzeugung der Datenquellen wurde vorher anders gehandhabt aber soll nun so geändert werden.Firefighter schrieb:
Wäre ein Interface nicht angebrachter, wenn du das implementierst, ist "Zwang-Faktor" zwar nicht höher, aber du siehst wenigstens direkt was du noch alles implementieren musst und bekommst eine NotImplemented Exception bei nicht Implementierung.
Naja in der Basisklasse existieren nicht nur abstrakte Methoden. Am besten wäre wohl, wenn man in Basisklasse und Interface aufsplittet oder so. Aber wie gesagt, ich draf mich nur damit rumärgern aber nichts schon bestehendens ändern.
-
Ich muss sagen, dass ich dein Problem noch nicht mal so richtig verstanden habe. Könntest du vielleicht mal etwas Pseudo-Code oder ein kleines kurzes Beispiels von deinem Problem erstellen. Würde irgendwie dem Verständnis beitragen, was du eigentlich erreichen willst und wie die Klassen zueinander stehen.
Grüssli
-
Ok ein bischen Pseudocode:
public abstract class Base { // enthält ein paar Methoden die abgeleitete Klassen benötigen // und gibt eine Schnittstelle, die implementiert werden muss } public class DatenquelleXYZ : Base { // implementiert den Zugriff auf eine Datenquelle (zb. Datenbank, Datei, Webservice, etc.) } public class Manager { // Singelton // prüft beim Initialisieren, für welche Arten von Datenquellen Implementierungen vorhanden sind // und verwaltet alle offenen Datenquellen }
Ich würde gern in der Basisklasse eine Methodensignatur für die Erzeugung einer Datenquelle festlegen. Mit Erzeugung meine ich nicht die Instanzierung einer Klasse DatenquelleXYZ sondern die Erzeugung der Datenquelle selbst (zb. DatenquelleDatenbank.Erzeuge() -> legt Datenbank + Tabellen an).
Das Problem:
Wenn nun zb. keine Datenbank vorhanden ist, kann ich auch keine DatenquelleDatenbank instanziieren, da mir einfach bestimmte Werte fehlen. Deshalb müsste die Erzeuge() Methode static sein und für static Methode kann man nun mal keine Signatur vorgeben.Wie oben schon geschrieben, kann ich den vorhandenen Code nicht ändern sondern nur erweitern. Und mir fällt einfach keine schöne, saubere Lösung ein.
Noch eine anderes Problem:
Ich hatte überlegt, für alle Datenquellen, für die .NET einen ADO-Provider bereitstellt, einen Basiszugriffsklasse zu schreiben.
Die Basiszugriffsklasse arbeitet also einfach mit System.Data.SqlClient.SqlConnection und die abgeleiteten Klassen erzeugen eine konkrete ADO-Connection.System.Data.SqlClient.SqlConnection connection = new System.Data.OracleClient.OracleConnection();
ADOSource.cs(25,25): Error CS0029: Cannot implicitly convert type `System.Data.OracleClient.OracleConnection' to `System.Data.SqlClient.SqlConnection' (CS0029)
Auf http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleconnection.aspx sieht man natürlich, dass es so garnicht gehen kann, da die Ableitungshierachie nicht passt. Ist es trotzdem irgendwie möglich sowas umzusetzen (außer mit Templates)?
-
wyfrn schrieb:
Auf http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleconnection.aspx sieht man natürlich, dass es so garnicht gehen kann, da die Ableitungshierachie nicht passt. Ist es trotzdem irgendwie möglich sowas umzusetzen (außer mit Templates)?
Warum verwendest du nicht den System.Data.Common -namespace? DbConnection und Konsorten. Da gibt es doch auch schon eine abstrakte Fabrik zum Erzeugen solcher Objekte.
-
witte schrieb:
wyfrn schrieb:
Auf http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleconnection.aspx sieht man natürlich, dass es so garnicht gehen kann, da die Ableitungshierachie nicht passt. Ist es trotzdem irgendwie möglich sowas umzusetzen (außer mit Templates)?
Warum verwendest du nicht den System.Data.Common -namespace? DbConnection und Konsorten. Da gibt es doch auch schon eine abstrakte Fabrik zum Erzeugen solcher Objekte.
Danke für den Hinweis. Das liegt einfach daran, dass ich mit ADO.NET noch nich so viel Erfahrung hab.
-
http://de.wikipedia.org/wiki/Fabrikmethode
oder was ähnliches
-
@wyfrn,
Und woher soll Manager überhaupt von den vorhandenen Datenquellen und den zugehörigen Klassen erfahren? Da habe ich irgendwie Probleme, dich zu verstehen. Manager muss ja wissen, was er instanzieren möchte. Sobald du uns erklärst, woher er dieses Wissen hat, kann man dir die Möglichkeiten auflisten.Grüssli
-
Du kannst dir ein eigenes Attribut implementieren, und das hängst du dann an alle abgeleiteten Klassen dran.
Darin kannst du die Daten hinterlegen die die Manager/Factory Klasse braucht um zu wissen was sie machen soll.
-
hustbaer schrieb:
Du kannst dir ein eigenes Attribut implementieren, und das hängst du dann an alle abgeleiteten Klassen dran.
Darin kannst du die Daten hinterlegen die die Manager/Factory Klasse braucht um zu wissen was sie machen soll.ähnlich wie hier - http://x8bit.de/index.php?option=com_content&view=article&id=70&Itemid=79&lang=de