phpbar.de logo

Mailinglisten-Archive

[php] Objekte: Instanzierung nur in der Factory zulassen und nicht ausserhalb

[php] Objekte: Instanzierung nur in der Factory zulassen und nicht ausserhalb

Marco Weber marco.weber at uni-trier.de
Fre Okt 10 16:48:15 CEST 2008


Hallo Martin,

Im Prinzip läuft unser Code so:

class userManager {
   private static $user_objects = array();

   public static function getUserById($id) {
     if (isset(self::$user_objects[$id])) {
       self::$user_objects[$id] = new user($id);
     }

     return self::$user_objects[$id];
   }
}

Ein Programmierer, der die API nutzt hätte nun zwei möglichkeiten:
1. der richtige Weg:
	$object=userManager::getUserById(1);
2. der falsche Weg:
	$object=new user(1);

Mit dem 2. Weg ist es sehr Wahrscheinlich, dass mehere Objekte für den Selben Benutzer erstellt werden...
Und das ist ein Problem... Denn die Objekte sind so designt, dass sie im Konstruktor zuerst alle Infos von der Datenbank laden und erst im Destruktor wieder schreiben. Durch den userManager wird sichergestellt, dass eben kein Objekt zu einem User A mehrmals vorkommt und somit, wenn was geändert wird am objekt, dass auch bei allen referenzen direkt geändert ist.
( Wenn nun aber jemand den 2. Weg nimmt, dann kriegen wir Probleme, weil dann eine Änderung nicht mehr in die DB kommt. )

Wie kann ich denn verhindern, dass jemand "$object=new user(1);" direkt aufrufen kann?
Oder anderst rum gefragt, wie kann ich nur zulassen, dass "userManager::getUserById(1);" zum Instanzieren von der user Klasse benutzt wird?

Grüsse
	Marco 


Martin Adler schrieb:
> Hallo Marco,
>
> die Fragestellung ist vielleicht nicht ganz eindeutig.
> Wenn von der Benutzerklasse nur eine einzige Instanz erlaubt ist, wäre 
> das Singleton-Pattern doch ausreichend?
> http://www.professionelle-softwareentwicklung-mit-php5.de/design-patterns.creational-patterns.singleton.html
>
> Wenn nun durchaus mehrere Instanzen erlaubt sein sollen, jedoch keine 
> Instanz einen Zwilling haben darf (also mehrere Instanzen von Benutzern 
> mit identischer ID), so müsstest du das Singleton-Pattern etwas anpassen.
> class Singleton {
>    private static $instances = array();
>
>    public static function getInstance($id) {
>      if (isset(self::$instances{$id})) {
>        self::$instances{$id} = new Singleton;
>      }
>
>      return self::$instances{$id};
>    }
> }
>
> Singleton kann man das dann wohl auch nicht mehr nennen.
>
> Das Proxy-Pattern Beispiel hilft dir evtl. den obigen vorschlag 
> nachzuvollziehen.
> http://www.professionelle-softwareentwicklung-mit-php5.de/design-patterns.structural-patterns.proxy.html
>
> Wenn auch hier nicht die erhoffte Antwort dabei sein sollte einfach noch 
> mal präzisieren :-)
>
> g,
> Martin
>
> Marco Weber wrote:
>   
>> Hallo,
>>
>> Also ich hab mal eine Frage:
>>
>> Wir schreiben gerade für ein grösseres Projekt eine eigene API.
>> Im moment haben wir z.B. ein User-Objekt.
>> Jeder benutzer hat ein eigenges Objekt als Singleton.
>> Also z.B. das Objekt für den User A existiert auch nur 1 einziges Mal
>> egal wie oft man es haben möchte.
>> Das User-Objekt könnte man unter Angabe der richtigen Parameter zwar
>> direkt mehrmals Instanzieren.
>> Aber man sollte halt besser die Factory Benutzen, die sicherstellt, dass
>> es nur einaml Instanziert wird und sonst die passende Referenz zurückgibt:
>> userManager::getUserById(1);
>>
>> Da also nur die Klasse userManager user Objekte erzeugen soll, kam nun
>> die Frage auf, wie man in das am besten so macht, dass sich user-Objekte
>> nur von userManager erzeugen lassen. (Und nicht von Hand)
>>
>> Meine erste Idee wäre, dass man beim Konstruktor des User Objektes ein
>> Token Übergeben muss. ( Das sollte zumindest etwas abschrecken, ist aber
>> keine befriedigende Lösung )
>>
>> Gibts da noch was besseres, was man tun könnte?
>>
>> Grüsse
>>     Marco
>>     


php::bar PHP Wiki   -   Listenarchive