Laden...

Static variable -> GoodPractice/BadPractice in meinem Fall?

Erstellt von IamTheBug vor 7 Jahren Letzter Beitrag vor 7 Jahren 1.543 Views
I
IamTheBug Themenstarter:in
401 Beiträge seit 2006
vor 7 Jahren
Static variable -> GoodPractice/BadPractice in meinem Fall?

Hallo,

meine Situation ist folgende:

Ich schreibe ein kleines Plugin für ein Programm. Die Spezifikation sieht vor das meine Plugin-dll eine Klasse enthalten muss die von der abstrakten Klasse "CustomPlugin" ableitet.
CustomPlugin wird dabei von dem Hauptprogramm bereit gestellt.
Das Hauptprogramm sucht in der dll nach der Klasse und lädt diese. Es gibt diverse Funktionen funktionen die die abstrakte Klasse bereit stellt und die ich dann überschreiben kann oder implementieren muss.

Weiterhin stellt das Hauptprogramm über die abstrakte Klasse Eigenschaften bereit. Diese Eigenschaften verweisen auf sogenannte "Manager". Mit der Verwendung der Manager z.B. DrawManager kann mein plugin das Hauptprogramm veranlassen etwas in sein Fenster zu zeichnen.

Soweit so gut.
Jetzt besteht mein Plugin aber nicht nur aus einer Klasse in einer Datei sondern aus mehreren.
Jetzt bin ich jedesmal dabei in jeder Klasse per Dependency Injection im Konstruktor diesen Manager und andere zu übergeben. Das ganze ist natürlich sehr nervig.

Meine Frage:
Kann ich nicht einfach eine statische Eigenschaft des Managers in meiner Hauptklasse erstellen und alle anderen Klassen greifen dann einfach darauf zu? Ist das schlechter Programmierstiel?

Rahmenbedingung sind auch das dieses statische Plugin nur einen Getter hat und nicht verändert werden kann.
Die Manager verändern sich durch das Hauptprogramm auch nicht, sie bleiben die ganze Zeit die selben nach dem initialisieren.
In Hinsicht auf TestBarkeit könnte ich meinen Klassen zusätzlich noch öffentliche Eigenschaften spendieren um den Manager der einzelnen Klassen expliziet zu setzen, so das diese Klasse nicht auf die statische Eigenschaft der Hauptklasse zurück greift.

GoodPractice/BadPractice? Gibt es andere Vorschläge?

Kurzes Beispiel wie ich es mir vorstellen anstatt in "MyOtherClass" im Constructor alle Manager zu übergeben.



    public class MyPlugin : CustomPlugin
    {
        public static IDrawManager StaticDrawManager { get; private set; }

        //wird vom Hauptprogramm durch CustomPlugin bereitgestellt
        protected IDrawManager DrawManager { get; }

        public override void Initialize()
        {
            //Methode wird vom Hauptprogram gerufen, initialisiere etwas

            StaticDrawManager = DrawManager;
        }
    }

    public class MyOtherClass
    {

        public MyOtherClass()
        {
            //beim initialisieren hole statischen Manager
            DrawManager = MyPlugin.StaticDrawManager;
        }

        //kann aber für UnitTests oder andere Dinge von aussen überschrieben, "umgebogen" werden
        public IDrawManager DrawManager { get; set; }

        public void DrawSomeThing()
        {
            DrawManager.DrawLine();
        }
    }


Mfg

IamTheBug

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo IamTheBug,

ich bin mir nicht sicher ob ich dich richtig verstanden habe. Aber wäre eine Basisklasse eine Alternative? Darin injectest du deine "Manager" und jede Klasse - "MyOtherClass" in dem Fall - leitet davon ab? Dann brauchst du nix statisches.

Gruss

Coffeebean

I
IamTheBug Themenstarter:in
401 Beiträge seit 2006
vor 7 Jahren

Das wäre eine Idee aber dann "verbaue" ich mir das Vererben. Ich kann dann ja von keiner anderen Klasse mehr erben, falls dies mal notwendig sein sollte.

Ausserdem muss ich den Manager ja trotzdem mit übergeben:



    public abstract class MyBaseClass
    {
        public MyBaseClass(IDrawManager drawManager)
        {
            DrawManager = drawManager;
        }
        protected IDrawManager DrawManager { get; }
    }

    public class MyOtherClass : MyBaseClass
    {

        public MyOtherClass(IDrawManager drawManager) : base(drawManager)
        {

        public void DrawSomeThing()
        {
            DrawManager.DrawLine();
        }
    }

Diese Übergabe die im Construktor von MyOtherClass geschieht, die wollte ich eigentlich los werden.

Mfg

IamTheBug

2.207 Beiträge seit 2011
vor 7 Jahren

Hallo IamTheBug,

hach ja, als ich es abschickte fiels mir wieder ein. Bringt wenig wenn du der Kind-Klasse wieder alles im ctor mitgeben musst.

Nächste Idee: Machst eine Fassade für all deine Manager und injectest diese.

Dann mit

_managerFacade.DrawManager.DrawSomething()

verwenden.

Gruss

Coffeebean

I
IamTheBug Themenstarter:in
401 Beiträge seit 2006
vor 7 Jahren

Danke für die Anregungen bisher.

Das mit der Facade ist mein aktueller Ansatz. Das ist auch so umgesetzt. Allerdings bin ich "genervt" von dem Injecten in jeder Klasse und wollte davon weg. Denn eigentlich greifen ja wirklich alle Klassen auf den selber Manager zu der vom Hauptprogramm bereit gestellt wird.
Im Moment mit der Facade klappt alles.
Ich wollte eben nur wissen ob es ein schlechter Ansatz ist auf diese Static Getter umzusatteln.

Mfg

IamTheBug

F
10.010 Beiträge seit 2004
vor 7 Jahren

Du solltest aufhören beim entwickeln zu denken was weniger arbeit macht.

Du solltest immer Testbarkeit in den Vordergrund stellen.
Und da fast jeder Container das PropertyInjecten auch beherrscht, ist das hier auch nicht soo schwer.