Announcement

Collapse
No announcement yet.

Factory Pattern - Konstruktoren abschotten

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Factory Pattern - Konstruktoren abschotten

    Hallo zusammen,

    ich möchte gerne in meinen Anwendungen Factories für die einzelnen Klassen benutzen. Ich habe mir dazu schon eine Menge Beiträge im Internet durchgelesen, stoße aber immer wieder auf das gleiche Problem und finde keine Lösung dafür:

    Wie kann ich die Konstruktoren der Klassen so abschotten, dass nur die Factory eine Instanz erstellen darf? Sonst habe ich irgendwann das Problem das doch jemand anfängt die Klassen direkt zu implementieren und das soll auf jeden fall vermieden werden.

    Eine Lösung wäre die Konstruktoren Friend zu deklarieren, dann muss ich aber alles in eine extra Assembly packen. Ist auch irgendwie nicht so schön.
    Ich habe auch irgendwo gelesen, das man die Klassen abstrakt deklarieren kann, habe dafür aber kein Beispiel gefunden wie ich dann in der Factory damit umgehen soll/muss.

    Kann mir hier vielleicht jemand einen Tipp geben wie ich mein Problem lösen kann?

    Vielen Dank schonmal.

    JenneB

  • #2
    http://de.wikipedia.org/wiki/Abstrakte_Fabrik
    Christian

    Comment


    • #3
      Erstmal danke für die schnelle Anwort.

      Um dann mal im Beispiel von Wikipedia zu beleiben:

      Wie kann ich denn verhindern, dass sich jemand im Klient eine Instanz vom KonkretesProdukA1 erstellt? Wenn ich das richtig verstehe sollte er die abstrakte Factory verwenden kann sie aber theoretisch umgehen. Oder habe ich da einen Denkfehler?

      Comment


      • #4
        Warum sollte das verhindert werden?
        Um ein Produkt A zu erstellen sollte man die Factory benutzen. Das sollte aber m.E. keinen Einfluß darauf haben von der Klasse KonkretesProdukA1 abzuleiten. Hier wäre dann zu diskutieren, von diese Ableitung ein weiters Produkt ist, welches eigentlich von KonkretesProdukA1 abzuleiten wäre, oder ob es Gründe gibt A1 zu überladen und es ist das gleiche Produkt
        Christian

        Comment


        • #5
          Es geht mir nicht ums ableiten. Es geht mir um das Erstellen einer Instanz. In dem Beispiel seht, folgendes verwenden soll:

          Code:
          Dim t As KontretesProduktA1 = factory.ErzeugeProduktA(
          )

          Was verhindert aber, das ich folgenden Aufruf mache:

          Code:
          Dim t As New KonkretesProduktA1()
          Es wird lediglich gesagt das man die Factory verwenden sollte, aber nicht das es nicht auch anders geht.

          Comment


          • #6
            Also was mir jetzt dazu einfällt, aber ich weiss nicht genau obs so funktioniert, ist den Konstruktor per Reflection aufzurufen und den Konstruktor in der Klasse protected zu machen.

            So kann er von aussen nicht aufgerufen werden jedoch per Reflection.

            Das kann natürlich auch jeder andere machen, aber wird er wohl nicht

            Comment


            • #7
              Danke, das werd ich auch mal probieren.

              Ich habe jetzt heraus gefunden wie das mit dem MustInherit funktionieren kann:

              Code:
              Public MustInherit Class Person
              
                    '... Der Code ...
              
              End Class
              
              Public Class DieFactory
              
                 Public Class ImplPerson : Inherits Person : End Class
              
                 Public Function GetNewPerson() as Person
                        Return New ImplPerson()
                 End Function
              
              End Class
              Ich weiß nur nicht wie sauber das ist. Macht das Sinn eine Facotry so auf zu bauen?

              Comment


              • #8
                Code:
                Return New ImplPerson();
                Du kannst den Konstruktor immer noch so aufrufen, oder? Ich denke manchmal sollte man die Abschottung des Codes nicht zuuu weit treiben. Warum sollte sich denn der Benutzer nicht selbst ein Objekt des jeweiligen Typs erzeugen können? Ich sehe die Factory mehr als ein Hilfsobjekt was mir die Objekte richtig zusammen baut, nicht als absoluten Weg die Objekte zusammen zu bauen.

                Entspricht MustInherit in VB.NET dem abstract in C#?

                Comment


                • #9
                  Hi,

                  ja, entspricht es.

                  Das Problem ist halt, dass ich noch keine gute Möglichkeit gefunden habe die Objekterstellung auf bestimmte Bereiche zu beschränken, wie es z.B. mit dem Friend Modifier in Java funktioniert. Da kann man dann nur innerhalb eines Packages (hier Namespaces) auf die einzelnen Konstruktoren zugreifen.

                  Ich habe halt, bzw sich noch immer nach einer Lösung dies in .NET auch zu haben.

                  Ich will die Beschränkung auch deswegen haben, damit man immer einen einheitlichen weg gehen muss um Kollegen einfacher an ein bestimmtes Projektkonstrukt zu "lenken".

                  Gruß

                  JenneB

                  Comment


                  • #10
                    dem Friend Modifier in Java funktioniert
                    ????

                    http://java.sun.com/j2se/1.5.0/docs/.../Modifier.html
                    Christian

                    Comment


                    • #11
                      Ich habs man kann den Constructor internal machen, dieser ist dann nur innerhalb der Assembly sichtbar:

                      [highlight=c#]
                      public class InternalConstructorClass
                      {
                      public String TestString { get; set; }

                      internal InternalConstructorClass(String test)
                      {
                      TestString = test;
                      }
                      }

                      public static class InternalConstructorFactory
                      {
                      public static InternalConstructorClass Create(String test)
                      {
                      return new InternalConstructorClass(test);
                      }
                      }
                      [/highlight]

                      Benutzen kannst Du das dann so (in einer anderen Assembly natürlich):

                      [highlight=c#]
                      InternalConstructorClass test = InternalConstructorFactory.Create("test");

                      //Das geht nicht
                      //var test = new InternalConstructorClass();
                      [/highlight]

                      Comment


                      • #12
                        @Christian Marquardt:
                        Sorry, hab mich vertan. Aber irgendeinen Modifier gab es dafür doch...

                        @fanderlf
                        Danke, aber das ist genauso wie ich das in meinem ersten Beitrag geschrieben habe

                        Eine Lösung wäre die Konstruktoren Friend zu deklarieren, dann muss ich aber alles in eine extra Assembly packen. Ist auch irgendwie nicht so schön.
                        Ich denke ich werde das jetzt mal ohne den Modifier probieren. Dann kann ich mich zumnindest auf einen Namespace beschränken. Vielen Dank an alle die mit überlegt haben.
                        Zuletzt editiert von JenneB; 22.02.2010, 19:17.

                        Comment


                        • #13
                          Ich denke ich würde das Thema einfach nicht überbewerten. Klar kann ich den Gedanken verstehen, aber wenn man sich dabei beide Arme brechen muss nur damit es so ist, dann mach ichs doch lieber etwas einfacher und dafür nicht ganz so sicher.

                          Comment


                          • #14
                            dann mach ichs doch lieber etwas einfacher und dafür nicht ganz so sicher.
                            Vor allem dann wenn diese scheinbare Sicherheit das Ganze so unflexibel macht das man das Zeug gar nicht verwenden möchte


                            Das zu verhindern ist für mich wenig sinnig. Verhindern kannst du es ja nur wenn du konkrete Klasse und Fabrik in die selbe Assembly packst und das Ganze dann wie bereits angemerkt über die Sichtbarkeit steuerst. Durch referenzieren der Fabrik (musst du um an ein konkretes Objekt zu kommen auch wenn du nicht direkt an das konkrete Objekt kommst) hast du auch indirekt die konkrete Klasse referenziert. Eigentlich ist der Sinn einer Fabrik aber die konkrete Klasse leicht austauschen zu können was du hiermit erschwerst da du dafür immer die Assembly umprogrammieren müsstest.

                            Sinnvoller ist da die Trennung von Fabrik, Interface und konkreter Klasse in drei verschiedene Assembly. Benutzer der Klassen sollten nur Fabrik und Interface referenzieren dürfen. Referenzieren von Assemblies mit konkreten Klassen dann per 'Codierrichtlinie' verbieten. Referenzieren der Assemblies mit konkreten Klassen darf dann nur der Code(in einer weiteren Assembly) der die Konfiguration der Fabrik vornimmt.

                            Comment


                            • #15
                              Muss der konkrete Typ des Objekts aus der Factory der Anwendung nicht bekannt sein? Also muss die Anwendung dann die Assembly des konkreten Typs nicht referenzieren?

                              Comment

                              Working...
                              X