php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > PHP Developer Forum
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 05-03-2007, 22:34
ZombieChe
 Member
Links : Onlinestatus : ZombieChe ist offline
Registriert seit: Apr 2004
Ort: Hannover
Beiträge: 225
ZombieChe ist zur Zeit noch ein unbeschriebenes Blatt
ZombieChe eine Nachricht über ICQ schicken
Standard [OOP] richtig strukturieren...

Hallo Leute,
bin in letzter Zeit ein wenig dran, mir die objektorientierte Programmierung reinzupfeifen, bin mir aber immer noch nicht sicher (und finde diesbezüglich auch irgendwie nichts), wie ein OOP System aussehen sollte. Da das natürlich für alles unterschiedlich sein kann hier mal ein Beispiel von mir für ein Browsergame (jaja, lacht nur...):

Es gibt eine SQL Klasse 'connection', die die Datenbank steuert.

Nun war meine Idee die folgende: Jede weitere Klasse ist Kindklasse von Connection und dient somit als Schnittstelle zur Datenbank, z.B.:

class user extends connection {...}
class character extends connection {...}
class message extend connection {...}
etc.

Nun instantiiere ich zu Beginn des Scripts sämtliche Klassen, die ich gebrauchen könnte (user, character, party), wo auch schon mein Problem liegt.
Das ganze scheint mir total Banane zu sein insbesondere da ich die Klassen nur auf einzelne Objekte beziehe (z.B. nur ein user) und ich somit mit diesen Klassen keine Übersicht aller Objekte hinbekomme (oder nur sehr aufwendig...).
Nun dachte ich an eine Realisierung in der Art wie Javascript es hat, also statt:
$user = new user($session_id());
$character = new character($user->character);
$character->name

sowas:

$user[$session_id()]->character->name

wobei dann in der klasse user natürlich die unterklassen angelegt werden müssten...

Wollte da mal die Meinung nach Sinn und Vorgehen bei sowas haben (auch allgemeiner), bzw. falls existent gerne auch Verweise auf entsprechende Tuts.
Danke schonmal

Geändert von ZombieChe (05-03-2007 um 22:36 Uhr)
Mit Zitat antworten
  #2 (permalink)  
Alt 06-03-2007, 09:19
PHP-Desaster
 PHP Expert
Links : Onlinestatus : PHP-Desaster ist offline
Registriert seit: Mar 2006
Beiträge: 3.105
PHP-Desaster befindet sich auf einem aufstrebenden Ast
Standard

Normalerweise macht man es mit der Datenbank-Klasse ganz gerne so, das sie als Singleton angelegt wird. So hast du lediglich eine Verbindung zur Datenbank (jede deiner Unterklassen hätte ja sonst eine eigene Verbindung) und du kannst aus jeder Klasse heraus darauf zugreifen.
Deine User oder Character sind schonmal ein wenig verwirrend, denn was ist denn jetzt was? Für mich hört sich das vom Namen her so an, als sei beides das gleiche!
Generell würde ich User, da sie ja lediglich Daten in sich tragen, als eine Unterklasse von ArrayObject anlegen und weitere Methoden, wie store() zum Speichern in der Datenbank usw. hinzufügen.
Um dann Aktionen zum Erzeugen eines User durchführen zu können, kannst du dann entweder deinem Konstruktor die User-ID mitgeben und der User erstellt sich selbst, oder du baust dir eine Klasse UserManager oder soetwas, welche dir User erbauen kann. Diese Klasse hat dann eine Methode createUser( id ).

Vielleicht hilft dir das ja schonmal weiter! Und du erklärst uns einmal den Unterschied zwischen User und Character!
Mit Zitat antworten
  #3 (permalink)  
Alt 06-03-2007, 09:55
closure
 Master
Links : Onlinestatus : closure ist offline
Registriert seit: Mar 2006
Beiträge: 796
closure ist zur Zeit noch ein unbeschriebenes Blatt
Standard Re: [OOP] richtig strukturieren...

Zitat:
Original geschrieben von ZombieChe
Es gibt eine SQL Klasse 'connection', die die Datenbank steuert.

Nun war meine Idee die folgende: Jede weitere Klasse ist Kindklasse von Connection und dient somit als Schnittstelle zur Datenbank, z.B.:
Nee, das ist murks. Ein user ist keine connection.
Ein user hat eine connection, mit der er arbeiten kann.
Wenn du willst das zustände der objekte in der datenbank
abgelegt werden können, dann könntest du eine abstrakte
klasse DBStorable oder so anlegen. Diese klasse hat dann wieder
eine datenbankverbindung und deklariert die abstrakten methoden
store und load. Jede der kindklassen implementiert die beiden
methoden so wie sie es brauchen.

Bsp.:
PHP-Code:
abstract class DBStorable{
      protected 
$db_connection;
      abstract protected function 
store();
      abstract protected function 
load();
}

class 
User extends DBStorable{

Damit hast du ein interface für die persistenz und jede
klasse die es angeht hat durch ihre basisklasse eine verbindung
zur datenbank.

Zitat:
Nun instantiiere ich zu Beginn des Scripts sämtliche Klassen, die ich gebrauchen könnte (user, character, party), wo auch schon mein Problem liegt.
Das ganze scheint mir total Banane zu sein insbesondere da ich die Klassen nur auf einzelne Objekte beziehe (z.B. nur ein user) und ich somit mit diesen Klassen keine Übersicht aller Objekte hinbekomme (oder nur sehr aufwendig...).
Hier kommen statische methoden ins spiel.
Beispielhaft die klasse user.

PHP-Code:
//die eigenschaften eines konkreten benutzers sind
//hier mal ganz banal
//Wenn du eine ORM-framework benutzt ist das viel einfacher
class User{
     private 
$name;
     private 
$age;
     private 
$id;
     public function 
__construct($name,$age,$id){
           
$this->name $name;
           
$this->age $age;
           
$this->id $id;
     }
    static public function 
find($id){
         
$con  DB::getInstance();
         
$res $con->query("SELECT name,age,id FROM `user`  WHERE id = ?"$id);
         if(
$res){
            return new 
User($res['name'],$res['age'],$res['id']);
         }else{
            return 
null;
         }
    }
   
   static public function 
find_all(){
        
$con DB::getInstance();
        
$res $con->query("SELECT * FROM user");
        
$users = array();
        
        if(
$res){
           foreach(
$res as $cur){
               
$users[]= new User($cur['name'],$cur['age'],$cur['id']);
           }
       }
       return 
$users;
   }
 
   
//static public function find_by_name($name);

Ich denke du weisst worauf es hinausläuft. Ein konkreter user
wird durch eine instanz der klasse user modelliert. Der zugriff
auf die user-tabelle wird durch die klasse und deren statische
methoden modelliert.

Hier sieht man wiederkehrende muster die man noch refaktorieren
kann, aber das überlass ich dir.

Als allgemeiner tipp. Es geht nur um mustererkennung. Wenn sich
etwas wiederholt oder ähnlich aussieht, denke darüber nach ob
man es abstrahieren könnte sodass man die muster wegkapseln
kann und sich nicht ständig wiederholen muss. Wenn dir etwas
zu kompliziert erscheint dann steige eine stufe höher in der abstraktion.
Es gibt kein problem dass sich nicht durch einen zusätzlichen layer
der indirektion lösen liesse.

Achte darauf dass deine klasseintefaces so groß wie nötig und so
klein wie möglich sind. Achte darauf dass jede klasse wirklich nur
das tut wofür sie gedacht ist.

Ich hoffe das hilft dir etwas.

greets

[EDIT]
Jetzt ist user allerdings nicht mehr von DBStorable abgeleitet.
Wie löst man das nun?
__________________
(((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

Geändert von closure (06-03-2007 um 10:10 Uhr)
Mit Zitat antworten
  #4 (permalink)  
Alt 07-08-2007, 10:52
ZombieChe
 Member
Links : Onlinestatus : ZombieChe ist offline
Registriert seit: Apr 2004
Ort: Hannover
Beiträge: 225
ZombieChe ist zur Zeit noch ein unbeschriebenes Blatt
ZombieChe eine Nachricht über ICQ schicken
Standard

so, nun muss ich diesen Thread doch nochmal rauskramen *staubwegpust*. Vielen Dank erstmal für die Hilfe. Inzwischen hab ich mich ein wenig weiter mit OOP beschäftigt (z.B. auch mit Java), sodass ich nu auch alles nachvollziehen kann
Allerdings stoße ich da noch auf ein Beziehungsproblem, das sich für mich als schwierig erweist.

Folgende Realisierung möchte ich haben:

Ein Benutzer (Klasse User) besitzt Städte (Klasse City).
Eine Stadt besitzt einen Informationstext (z.B. die __toString() Methode) die folgende Daten enthält: Name - Bevölkerung - Besitzer

Jetzt stoße ich auf das Problem, dass die Klasse City ja genau genommen keine Info über den Benutzer hat, da sie ja ohnehin nur innerhalb der Klasse User verwendet wird. Jetzt boten sich mir mehrere Möglichkeiten, die mich aber alle nicht sonderlich ansprechen:

1. Ich mache die Benutzerinstanz global, um dann mit $user->name auf den Namen zuzugreifen.
2. Ich übergebe der Stadt beim Instanzieren eine weitere Instanzvariable $owner, um darauf zuzugreifen.
3. Ich rufe den Informationstext nicht aus der Klasse City, sondern aus der Klasse User auf (z.B. $user->printCityDescriptionOf($city_id) ), wodurch ich ja direkt Zugriff auf den Benutzernamen hätte.

Aber:
1. scheint mir nicht professionell, weil ich das Objekt ja auf eine Eben ziehe, wo es eigentlich nicht hingehört
2. wird etwas umfangreich wenn ich der Stadt z.B noch Gebäude gebe und das selbe Spiel nochmal anfängt (oder noch andere Infos benötigt werden)
3. scheint mir fehl am Platz zu sein und am Ende habe ich dann 50 Methode allein für Informationstexte in der Userklasse

Ich hatte auch versucht das komplette Userobjekt zu übergeben, aber letztendlich führt das ja zu einer Rekursion beim Zugriff:
$user->getStructure(1)->owner->getStructure(1)->owner->......


Ich wär für eure Hilfe echt dankbar, da mich das ganze ziemlich auf die Palme bringt und ich mir dadurch die ganze OO versaue....

Danke schonmal
ZC
Mit Zitat antworten
  #5 (permalink)  
Alt 07-08-2007, 11:39
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

Zitat:
1. Ich mache die Benutzerinstanz global, um dann mit $user->name auf den Namen zuzugreifen.
Einbahnstrasse! Du nutzt hier die Einzigartigkeit des User Objekts aus. Wenn du gleichzeitig mehrere User-Instanzen hast, weiß keine Stadt welches X in $users[X] ihr Besitzer ist.
Im Endeffekt machst du die Klasse User hintenrum zum Singleton.
Zitat:
2. Ich übergebe der Stadt beim Instanzieren eine weitere Instanzvariable $owner, um darauf zuzugreifen.
Ja so würde ich es machen.
Zitat:
3. Ich rufe den Informationstext nicht aus der Klasse City, sondern aus der Klasse User auf (z.B. $user->printCityDescriptionOf($city_id) ), wodurch ich ja direkt Zugriff auf den Benutzernamen hätte.
Damit hättest du das gleiche Problem wie bei 1. und außerdem fügst du Funktionalität ins User Objekt, die da nicht hingehört. Wenn man den Gedanken mal ganz weit überzieht, hat man am Ende einen omnipotenten User und alles andere sind nur taube Objekthülsen.
Mit Zitat antworten
  #6 (permalink)  
Alt 10-08-2007, 11:11
ZombieChe
 Member
Links : Onlinestatus : ZombieChe ist offline
Registriert seit: Apr 2004
Ort: Hannover
Beiträge: 225
ZombieChe ist zur Zeit noch ein unbeschriebenes Blatt
ZombieChe eine Nachricht über ICQ schicken
Standard

okay, genau genommen handelte es sich in dem Fall, den ich meinte, tatsächlich um ein eimaliges Userobjekt, da es den eingeloggten Benutzer modelliert. Hatte ihn zu Beginn nicht mit dem Singleton Pattern generiert, da es eine abgeleitete Klasse von User ist und der Konstruktor nicht private sein durfte...naja, vielleicht sollte ich das noch ändern.

Die Frage war ja eigentlich, ob es da nicht geschicktere Modellierungen gibt, da mir das "Durchschleifen" einer Information bis zum letzten Objekt sehr aufwenig vorkommt. z.B. folgender Baum:

$user->city->district->building->room->person

Wollte ich nun darstellen, welchem Benutzer die Person gehört, müsste ich den Namen des Benutzers bis zur Person durch alle Objekte mittragen. Möglich, aber ist das auch so üblich? Oder durchlauf ich hier ein Szenario, das es so ohnehin nie geben würde? Ich sollte echt mehr planen....
Mit Zitat antworten
  #7 (permalink)  
Alt 10-08-2007, 13:14
Benutzerbild von onemorenerd onemorenerd
  Moderator
Links : Onlinestatus : onemorenerd ist offline
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.471
onemorenerd wird schon bald berühmt werdenonemorenerd wird schon bald berühmt werden
Standard

$user->city->district->building->room->person ?
Ich nehme an es geht mal wieder um ein Browsergame ...
Im nächsten Level sind interstellare Hochzeiten möglich, was dich zu dieser Blüte treibt:
$user->$universe->solarsystem->planet->continent->country
->fedstate->city->district->building->floor->room->person
->righthand->fingers[4]->putOn($ring)


Du hast $user zum Universalobjekt gemacht. Und noch viel schlimmer, du modellierst alles streng hierarchisch.
OOP ist aber was ganz anderes als objektrelationale DBS. Du kannst jede Art von Beziehung modellieren, mehr als nur is-a/has-a und is-related-to wie bei DBS. Das ist auch nötig, denn Daten sind tot, aber Objekte re-/agieren (Stichwort Observer).

Wie wäre es denn hiermit?
Die Stadt gehört dem User: $city->owner == $user
Die Person gehört dem User: $person->master == $user
Kein Hierarchie mehr. Die Person kann den Besitzer wechseln ohne in eine andere Stadt ziehen zu müssen.

Geändert von onemorenerd (10-08-2007 um 13:17 Uhr)
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

ADSMAN V3 - Werbe-Manager ansehen ADSMAN V3 - Werbe-Manager

ADSMAN V3 - mehr als nur ein Bannermanager! Banner, Textanzeigen und PagePeel Manager! Mit ADSMAN PRO haben Sie die Marketinglösung für eine effektive und effiziente Werbeschaltung mit messbaren Ergebnissen. Unterstützt werden Bannerformate in beliebi

25.10.2018 virtualsystem | Kategorie: PHP/ Bannerverwaltung
PHP News und Artikel Script V2

News schreiben, verwalten, veröffentlichen. Dies ist jetzt mit dem neuen PHP News & Artikel System von virtualsystem.de noch einfacher. Die integrierte Multi-User-Funktion und der WYSIWYG-Editor (MS-Office ähnliche Bedienung) ermöglichen...

25.10.2018 virtualsystem | Kategorie: PHP/ News
Top-Side Guestbook

Gästebuch auf Textbasis (kein MySQL nötig) mit Smilies, Ip Sperre (Zeit selbst einstellbar), Spamschutz, Captcha (Code-Eingabe), BB-Code, Hitcounter, Löschfunktion, Editierfunktion, Kommentarfunktion, Kürzung langer Wörter, Seiten- bzw. Blätterfunktion, V

22.10.2018 webmaster10 | Kategorie: PHP/ Gaestebuch
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 19:23 Uhr.