Sie befinden sich hier im Forenarchiv von phpforum.de wenn Sie direkt ins Forum möchten, klicken Sie bitte hier. Zur Startseite kommen Sie hier.

auf methoden übergordneter klassen zugreifen

wie kann eine methode einer andere methode aufrufen, die einer klasse, in der klassen-hierachie über ihr gelgen, ist?

beispiel:

Code:                   In Zwischenablage kopieren (nur IE)
1">

ich befürchte, da muss ich auf php5 warten. das eigentliche problem ist, dass ich einemutter- klasse habe, in der methoden sind, die alle klassen brauchen. daher erben die verschiedene klassen immer diese mutter-klasse. es gibt aber einie methoden, die nur von einigen klassen gebraucht werden. also binden diese einige klassen diese speziellen klassen ein. nun müssen ein paar dieser speziellen eingebundenen klassen aber auch auf die methoden der mutterklasse zugreifen.

unelgeant, aber am einfachsten, wäre es natürlich einfach alle methoden in die mutterklasse zu hauen, die sich gegenseitig benutzen...

danke für die hilfe

der kal
Hier gehts zum Orginal Eintrag "auf methoden übergordneter klassen zugreifen" im Forum

Antworten

die Frage habe ich mal wieder nicht verstanden. Markier im Beispiel mal einfach, was Du mehr brauchst
Code:                   In Zwischenablage kopieren (nur IE)
2">




2.

esrtmal danke für den coolen support volker.!

es geht darum dass ich in einer methode eine objekt einer klasse erstelle und in dem neu erstellten objekt auf methoden zugreifen möchte die in der klasse sind aus herraus das genannte objekt erstellt wurde. natürlich kann man die gesamte 'alte' klasse vererben. dann hat man bar dieselbe klasse doppelt im speicher...

hab mein bsp versucht etwas verständlicher zu machen:

Code:                   In Zwischenablage kopieren (nur IE)
3">




3.

Du solltest nicht Klassen innerhalb von anderen Klassen definieren. Das ist zwar keine falsche Syntax, aber bringt auch nichts außer Unübersichtlichkeit. Benutze das Schlüsselwort "extends" wie Volker um Vererbung zu definieren.


4.

öhem, doch, das ist falsche syntax. php läßt keine nested-classes innerhalb von Funktionen zu.
Zitat:
PHP Fatal error: Class declarations may not be nested in blablabla
nested classes sind auch niemals instanceof der umgebenen Klasse; parent:: kann also nicht funktionieren.
Vermutlich geht es Dir um den Zugriff auf die member von aaa, aber da brächte Dir auch eine nested class keinen Vorteil - weder funktionell noch was den Arbeitsspeicher angeht.
Wolltest Du den code für KLasse b wirklich in der Funktion ausschreiben? - dann kannst Du es auch einfach an der Stelle ausprogrammieren; ohne weitere Klasse
Oder wolltest Du die andere Klasse an der Stelle includieren (also evtl. variabel)? In diesem Fall verpass entweder class aaa oder class bbb die notwendigen getter/setter-Funktionen und übergib ein Objekt der jeweils anderen Klasse in die Funktion der anderen. Da wird Dir php5 in der Tat etwas bringen, da Objekte dann per default als Referenz übergeben werden.


5.

Es geht auch nicht darum, dass ich die Klasse innerhalb der Klasse defniere. Das kann genauso extern geschehen. Es geht darum, dass ich zum Beispiel eine Klasse DbFunktionen und eine Klasse AdminFunktionen habe.

Dann habe ich zB eine Klasse Standard, die ich für jede Seite aufrufe. Wenn ich nun in Standard zB $this -> DbFunktion = new DbFunktionen mache. hab ich in meiner ganzen Klasse die Db Funktionen als $this->DbFunktion->einDbMethode zur verfügung. das finde ich sehr übersichtlich, zumal die DbFunktionen klasse wieder andere klassen einbinden kann und so eine hierachie entsteht.

problem ist, dass wenn ich nun ein objekt einer anderen klasse erstelle, zB mit $this->AdminFunktion = new AdminFunktionen , dass ich in dieser klasse auch auf DbFunktioen zugreifen möchte ohne irgendetwas doppelt zu includieren oder vererben zu müssen....


6.

Also jetzt versteh ich gar nichts mehr. *rat* Vielleicht möchtest Du die DB-Instanz per Methodenaufruf übergeben? Ne andere Möglichkeit gibts dann ja eigentlich gar nicht mehr. Das hat mit includieren und vererben eigentlich nichts zu tun.


7.

gard wurde scheinbar mein code verschluckt..
[coder]


<?php
class aaa {
function methode_von_a () {
echo "ich bin eine methode von aaa";
}

function noch_eine_methode_von_a () {
class bbb {
function methode_von_b() {
echo "unter mir soll was von aaa kommen:\n";
parant::methode_von_a(); // GEHT LEIDER NICHT!
}

bbb::methode_von_b();
}
}
}
?>

[/code]


8.

Du definierst ja immernoch eine Klasse innerhalb einer Klasse. Was soll denn das? Und "parent" funktioniert nunmal nur bei Vererbung. Vielleicht möchtest Du Dir die Doku zur Objektorientierung nochmal zur Gemüte führen? Ich habe irgendwie den Eindruck, als bringst Du da einiges durcheinander...


9.

Ich maße mir einfach mal an, in etwa verstanden zu haben, was Du möchtest. Daher gebe ich Dir einen gut gemeinten Tip: Vergiss dieses Konzept, denn "so macht man es einfach nicht". Hört sich blöd an, aber Du merkst ja selbst, daß es eigentlich ein Krampf ist.
Mach es lieber so, daß Du z.B. eine DB-Klasse schreibst, in der Du erstmal alle Funktionen, die den Zugriff auf die DB realisieren, kapselst. Davon leitest Du davon jeweils weitere klassen ab, z.B. eine mit Adminfunktionen und eine andere für den Rest.


10.

Ein schönes Konzept wäre es auch, eine Datenbank-Zugrifssklasse zu schreiben, davon eine Instanz zu erzeugen und diese Instanz an alle Objekte, die das brauchen, weiterzugeben. Z.B. mittels eines Methodenaufrufs oder schon im Konstruktor.


11.

Richtig, genau so passiert das in meiner Datenbanklib auch :-)
Aber Obacht: Immer schön darauf achten, daß man die Objekte mit "Call by Reference" übergibt!


12.

Och, auf diese Unterscheidung würd ich mal getrost verzichten und auf PHP5 warten ;)


13.

Dann könntest Du zumindest mit meiner Lib aber (noch) nicht richtig arbeiten, denn integraler Bestandteil ist z.B. ein Datenpuffer, der allen Tabellenobjekten gemein ist und zentral im Datenbankobjekt liegt. Das funktioniert natürlich nur, solange alle von demselben Datenbankobjekt sprechen...


14.

Na aber ein Datenpuffer, der nur für einen einzigen Seitenaufruf gilt, ist doch albern... oder nich?


15.

Im ersten Moment erschein es so... aber bedenke doch einfach mal, wie schön man die Datenkapselung hinbekommen kann. Kleine Kostprobe: Bei einem SELECT z.B. lade ich innerhalb des DB-Objekts sukzessive den aktuellen Datensatz (mit mysql_fetch_array()) in den Puffer, anschließend brauche ich nur noch für jeden Wert den ich haben will die get_value($field_name)-Methode des Tabellenobjekts aufrufen. Da das Tabellenobjekt natürlich weiß, was für ein Wert (integer, Datum etc.) in dem Feld steht, kümmert es sich auch gleich schon um die passende Formatierung, d.h. ich kann den Rückgabewert von get_value() direkt weiterverwenden.


16.

Wozu mand azu aber einen Datenpuffer braucht, weiß ich immernoch nicht.


17.

Ich farge mal so: Wie willst Du die von mysql_fetch_array() gelieferten Daten sonst im Tabellenobjekt bekannt machen? Ein SELECT bezieht sich ja in aller Regel auf n Tabellen.


18.

Ich glaube, wir sind soweit, dass wir ein Klassendiagramm zur Kommunikation brauchen :)


19.

Leider war mein Arbeitgeber nicht bereit, mir ein Tool wie "Together" zur Verfügung zu stellen, sonst hätte ich jetzt eins gepostet :-)


20.

hm also wenn ich das richtig verstanden hab das sollte kalles code wohl etwa so aussehen
Code:                   In Zwischenablage kopieren (nur IE)
4">

mit extends kann man heir glaub ich nur wenig anfangen. Man kann dann zwar auf die methoden und Eigenschaften von der Klasse aaa zugreifen, aber diese enthalten dann nicht die werte aus dem objekt "objaaa".
ich hoffe ich hab das problem richtig verstanden (ansonsten nehm ich alles zurück und behaupte das gegenteil :) )
ne lösung dafür weis ich allerdings auch nicht.


21.

So würde es klappen:

Code:                   In Zwischenablage kopieren (nur IE)
5">

Allerdings wird dann keine spezielle Instanz von aaa angesprochen, sondern gewissermaßen die Funktion als "Klassenfunktion" aufgerufen. Es gibt dann innerhalb methode_von_a () kein $this!


22.

vielen dank für die rege beteiligung!

leider kann kein thread das problem lösen.

wie baut ihr denn eine wepräsenz auf?

ich erstlle ein klasse, mit den funktionen, die auf jeder seite benötigt werden. dann erstelle ich für die einzelnen kategorien einzelne php files. in diesen wird dann eine neue klasse erstellt, die die hauptklasse erbt und natürlich neue methoden enthält.

so werden die einzelnen kategorien unterinander nicht vom code der anderen klasse belastet und verschiedene leute können gleichzeitig an dem selbem projet, nur unterschiedlichen kategorien arbeiten.

das proböem ist halt nur, wenn man methoden hat, die nur zwei, aber nicht alle kategorien brauchen. dann muss man diese entweder in die hauptklasse packen, wo sie alle 'belasten' oder in beiden php files schreiben...

gibt es eine funktion mit der man einer klasse methoden hinzufügen kann. leider kann man kein unclude nach dem style

class xyz {
include("methoden_bzw_funkitonen.inc.php");
}



wie macht ihr das?
thx

kal


23.

Wie gesagt, ich würde mir ein ganz anderes Modell überlegen. Bei mir gibt es z.B. prinzipiell für alle html-Elemente Klassen, z.B. html_td_object, html_a_object, html_form_object usw. usf. Es gibt bei mir natürlich noch eine html_base_class (Interfaceklasse), aber das mußt Du dir selbst überlegen wie Du das machst.

Dann gibt es Klassen für Datenbanken und Tabellen in Datenbanken.

Und dann gibt es noch ein paar wenige, mächtige Klassen in denen ich mit html und Datenbank-Objekten Arbeite. Um z.B. eine fertige html-Tabelle mit anklickbaren Spaltenüberschriften (zum Ändern der Sortierung) und einer Aufteilung in Seiten, die der Benutzer durch Klick auf die Seitenzahl wählen kann, zu erzeugen, ist dann nur noch folgender Codeschnipsel nötig:

Code:                   In Zwischenablage kopieren (nur IE)
6">




24.

hhmmm... sieht korrekt aus. leider verstehe ich es nicht.

> Wie gesagt, ich würde mir ein ganz anderes Modell überlegen

deshalb frag ich ja. ich hab ne menge zeit investiert um ein sinnvolles kenzept zu erstellen und ich komm die alternativen die ich durchgegeangen bin, haben wesentlich mehr naschteile. ledier konnte ich bisher kein gutes tut zu dem thema finden.

aher fragte ich auch wie ihr komplexe präsenen aufbaut, sodass jede funktion nur an einer stelle steht und nur einmal und auch nur wenn sie wirklich gebraucht wird in den speicher geladen wird...

kal


25.

Model View Controller Pattern.
Aufteilung primär nicht nach Webseiten, sondern nach Funktionalitäten: Datenbankklassen (Connectionpool etc), Beans, und was sich sonst noch so findet.
Weitere Klassen sind dann meist durch die Programmiersprache bedingt, da ich größeres normalerweise nicht mit PHP sonderne her mit Java löse, also zusätzlich noch Servlets brauche :)


26.

Ich mache das so:
Der Status meines Systems (Anm.: Es ist eine Datenbank, die bei uns in der Firma benutzt wird) wird durch zwei Statuswerte eindeutig beschrieben: Dem Kontext (CX) und dem Usecase (UC). Es gibt zu jedem Kontext eine gleichnamige Datei, die dann - je nachdem welcher Kontext gerade aktiv ist - über include() eingelesen wird. Innerhalb dieser Datei gibt es dann eine riesengroße switch()-Anweisung, die dann je nach Usecase die richtige Maske anzeigt.
Aber: Meine Objekte und Bibliotheken werden grundsätzlich _immer_ geladen, bei _jedem_ Seitenaufruf.


27.

Hm, also ich unterscheide erstmal zwischen den üblichen drei Schichten Präsentation, Logik und Datenbank. Bei der Präsentation hat es sich bewährt, ganz normales PHP mit HTML gemischt zu schreiben, die Logik besteht meist aus Controller- und Model-Klassen (ich nenne sie meistens "Manager" und "DataObjects"), während die Datenbank über eine einzige Klasse angesprochen wird, die nichts weiter macht als Datenobjekte zu lesen und zu schreiben. Durch das einfache Request-Response-Prinzip lässt sich so ein Drei-Schichten-Modell recht gut durchziehen.

Allerdings kümmere ich mich auch nicht wirklich darum, wie viele Dateien denn nun wirklich geladen werden, ich setze einfach ein "require_once" da rein, wo eine bestimmte Klasse benötigt wird. Somit weiß ich zumindest, dass immer nur die Klassen geladen werden, die gebraucht werden.

Manager-Objekte werden bei Bedarf dynamisch erzeugt, machnmal gibt es auch mehrere vom gleichen Typ. Da ich Manager-Objekte grundsätzlich zustandlos halte, gibt es da auch keine Probleme.


28.

Hallo Oimel!

So in etwa sieht das Modell bei mir auch aus, allerdings scheint es so daß ich meine Präsentationsklassen noch etwas weiter abstrahiert habe. Keine meiner PHP-Dateien sieht eigentlich nach klassischen html aus - eher ein bischen wie C, mit zahlreichen defines am Anfang usw. Nutzt Du auch Objekte, die in der Session gehalten werden, oder leben sie bei Dir nur während eines Durchlaufs?


29.

Nun, ich habe eben die Erfahrung gemacht, dass ein Abstrahieren der Präsentationsschicht für grafiklastige Websites so gut wie keinen Sinn macht - das mag bei Intranetanwendungen oder B2B-Anwendungen natürlich anders sein. Was ich habe sind z.B. Klassen zur sicheren (überprüften) Übertragung von Formularinhalten in Datenobjekte und umgekehrt, aber nicht viel mehr.

Sessionobjekte habe ich bisher selten gebraucht, je nach Bedarf eben. Wieso?


30.

Zitat:
oimel postete
Sessionobjekte habe ich bisher selten gebraucht, je nach Bedarf eben. Wieso?
Pure Neugierde um zu Erfahren, wie andere das lösen. Ich benutze übrigens sehr intensiv den Session-Mechanismus für Objekte; so speichert mein DB-Objekt z.B. die Datenbank-Struktur intern ab, die es selbsttätig aus der Datenbank liest. Das muß dann eben nur beim ersten Aufruf passieren und nicht bei jedem Klick. Das Session-Cookie wird dabei stets so vergeben, daß es um 0 Uhr des Folgetages abläuft, damit also am nächsten Tag auf jeden Fall eine neue Session erzeugt wird.

Das mit dem Abstrahieren der Präsentatsionsschicht kann bei html schon sehr viel Arbeit ersparen, wenn man es richtig machen will. Ich kann bei mir eine beliebige Seite hernehmen und durch den w3c Validator jagen, hatte als Ergebnis bislang noch nicht einmal warnings! Z.B. der Aufruf:

Code:                   In Zwischenablage kopieren (nur IE)
7">

erzeugt folgenden html-Quelltext:
Code:                   In Zwischenablage kopieren (nur IE)
8">

Ist doch nicht übel oder?


31.

Hoppla, der Quelltext ist geparsed worden... ein Forum-Bug? So sieht es eigentlich aus (hab mal Leerzeichen dazwischengefügt):

<i>Es w& auml;re sch& ouml;n, wenn niemand beim & lt;a& gt;-Tag das & quot;alt& quot;-Attribut vergi& szlig;t</i>


32.

Beim a Tag? Seit wann ist da ein ALT Attribut definiert? SCNR
Nun, ich finde ganz ehrlich den mechanismus noch immer nicht optimal, HTML Code per derartiger Klassen zu erzeugen. Ich finde hierfür Templates wirklich wunderbar passend. Man handelt sich zwar dummerweise eine weitere Abstraktionsebene zwischen HTML und PHP - eben die Template"sprache" - ein, aber dafür durch einen zusätzlich gewonnenen Freiheitsgrad.


33.

Zitat:
Oliver Albers postete
Beim a Tag? Seit wann ist da ein ALT Attribut definiert? SCNR
Ach stimmt ja... nun, vielleichte sollte ich mir angewöhnen, ab dem 5. Weizen nichts mehr über html-Tags in Foren zu posten ;-)

Zum Thema html-Klassen: Es kommt natürlich stark darauf an, was man darstellen möchte. In meinem konkreten Fall geht es wie gesagt um eine browsergesteuerte Datenbankank bei uns in der Firma, das Layout ist immer gleich und ohne großen Schnickschnack gehalten. Auf meiner privaten Seite mache ich das auch etwas anders, weil ich das nicht in so ein starres Schema pressen möchte. Zwar verbessert so ein starres Schema die Ergonomie (gut in der Firma), aber es sieht eben auch schnell langweilig aus (schlecht für die private Seite)...


34.

Ja, und heutzutage wollen sie doch alle bunte Seiten mit viel Schnickschnack :)


35.

na das ist ja eine richtig interessante diskussin geworden...

leider hats mir nicht wirklich helfen können. daher nochmal anders formuliert ds ganze:

angenommen wir haben eine dbClass und eine sessionClass.

jetzt aheb wir eine seite die eine bestimmte funktion anbietet z b ein beitrag posten.

hierzu erstellen wir eine klasse bspClass, in der es methoden gibt um die formulareingaben zu überprüfen und was auch immer noch...

jedenfalls brauchen einige der methoden die dbClass, also wird sie übergeben (als objekt natürlich).

natürlich wird auch überprüft ob man auch berechrigt was zu posten. dazu wird die sessionClass (als objekt) übegeben und eine entsprechende methode hierraus aufgerufen.

diese methode braucht aber, genause wie die mutterklasse und die meisten klassen sowieso, ebenfalls die dbClass, weil DBs ne zentrale rolle immer und überall spielen.

ist die einzige möglichkeit jeder klasse die dbClass neu zu übergebn. das ist doch unheimlich ineffektiv!

gibt es keine möglichkeit zu sagen: wir haben eine dbClass, eine sessionClass und eine bspClass. also verschmelzen wir alle zu einer großen und alle können auf alle zugreifen. leider kann man nur eine klasse erben, sonst wärs easy.


also, wenn jemand ein nettes konzept vorzuschlagen hat, her damit! es geht aber überhaupt nicht um dieses frei erfundene bsp.


danke und viel spass damit.

kal


36.

Also ich bleibe dabei: Du musst Dein Konzept ganz anders aufbauen, und ich würde auch nicht auf Teufel komm 'raus alles in Objekte packen. Denn Gott sei dank ist PHP ja kein Java; (eine Sprache, die ich übrigens abgrundtief verachte...).
Noch eine Idee für Dich: Erstelle Objekte für Deine Datentypen, die alle von einer Grundklasse, die als Interface dient, erben. Z.B. so:
Code:                   In Zwischenablage kopieren (nur IE)
9">

Um den Wert zu Speichern übergibst Du nun einfach Deinem DB-Objekt ein Objekt vom Typ warenkorb oder beitrag, und der Trick dabei ist, daß Dein DB-Objekt nur Methoden der gemeinsamen Oberklasse db_data_object benutzt.


37.

Was ich nun aber gern noch wissen möchte: Weshalb verachtest Du Java? Das ist die einzige Programmiersprache (ich glaube nach Algol), die ein 100%ig durchgängiges OO-Konzept anbietet, ohne dabei (wie C++) Elemente anzubieten, die das Konzept ad absurdum führen. Dass dabei die Ausführungszeit aus verschiedenen Gründen leidet ist liegt dabei nicht an den Konzepten der Sprache, sondern an anderen Designentscheidungen. Generell sind Entwicklungen in Java gegenüber C++ effektiver und stabiler, nur vielleicht nicht immer so schnell in der Ausführung.

Dafür ergeben sich ganz andere Möglichkeiten: Die extrem umfangreichen Standard-Bibliotheken, die Plattformunabhängigkeit, Applets, Java-Web-Start, Java Enterprise Beans, verteilte Anwendungen, moderne Benutzeroberflächen, ...


38.

OK, was mag ich an Java nicht:

1. Ich finde es sehr, sehr einschränkend, daß man bei Java für alles gleich mit dem "OO-Hammer" anrücken muß. Ich habe unter meinen Anwendungen gerne einen eher "prozedural designten" Unterbau, das hat sich bislang auch immer bewährt. Java schnürt mich da sehr ein; das ist zwar eher eine Gewohnheitsfrage, aber mich stört es eben. Es geht ja auch anders, siehe C oder eben PHP.

2. Die fertigen Bibliotheken sind (mir) einfach zu kompliziert. Für Dinge, die in C ein einfacher Aufruf einer libc-Funktion erledigt, muß ich in Java meistens gleich Unmengen an Packages einbinden (die nächste Woche sowieso anders heißen, je nachdem was gerade so Hip ist). Das ist schon krank - aber damit nicht genug: Weil jede Klasse natürlich irgendwie alles kann, hat sie natürlich kilometerlange Vererbungslinien wie java.lang.strings.git_nur_montags.erde.foo.hastenichgesehen.bla.fasel. und mindestens 2000 Methoden. Da habe ich dann schon meist keine Lust mehr, weiter zu suchen, wenn ich z.B. eigentlich nur mal eben kurz ein fprintf() gebraucht hätte.

3. Java ist eben wie Pascal nur was für Quiche-Fresser ;-)


39.

Hm, also dann scheint das eine reine Gewohnheitssache zu sein. Ich kann Dir jedes Deiner Argumente stichhaltig widerlegen, z.B. der OO-Hammer ist dafür verantwortlich, dass man mit Java im Team programmieren kann OHNE mehrseitige Coding-Richtlinien. Das habe ich bei C noch nicht erlebt.

Oder: Alle Standard-Bibliotheks-Klassen haben ihren Namen, ihr Paket und ihre Methoden seit der Einführung von Java beibehalten. Dass man für verschiedene Zwecke verschiedene Pakete importieren muss, liegt wohl eher daran, dass die Pakete gut strukturiert sind - im Gegensatz zu den Funktionen in C oder PHP.

Und: Die Vererbungshierachien sind in den Standard-Klassen sehr flach. Komplexe Bibliotheken wie Videobearbeitung oder 3D erfordern natürlich auch komplexere APIs - aber sowas gibt es in C und PHP ja nichtmal als Standard.

Außerdem: ICH MAG QUICHE! Irgendwelche Einwände dagegen? *böseguck*

Alles in allem: Ich beschäftige mich lieber damit, ein Produkt ordentlich zu konzeptionieren, als mich mit den Eigenschaften einer Sprache zu beschäftigen. So findet man z.B. in jedem größeren PHP-Projekt eigene und teilweise recht umständliche Lösungen, um effizient includes von Funktionen und Klassen aus bestimmten, konfigurierbaren Verzeichnissen auszuführen. Ist doch nervig, sich mit so nem Kram aufhalten zu müssen!


40.

zum thema jav kann ich wenig sagen. auf jeden fall ist php free. und dasist für mich derwichtigste punkt.

danke telefonmann für deinen code. leider hilft auch dieser mir nicht weiter, da warenkorb nicht auf methoden con beitrag zugreifen kann. außerdem haben wir dann db_data_objectdoppelt , was ineffektiv ist.

dun rätst mir zu einem komplett anderem prinzip. dieses prinzip ist ja nach dem ich frage! ich bin gern bereit das komplette konzept nweu zu gestalten. nur leider hab ich trotz wirklich langer beschäftigung mit dem thema php code aufbau keine gute lösung gefunden.

also her mit den konzepten!

danke
kal


41.

Moment, das einzige Problem ist, eine Instanz der Klasse dbClass überall zur Verfügung zu haben? Wieso musst du das dann überhaupt übergeben? Das SIngleton Pattern ist hier doch geradezu aufdringlichst geeignet.


42.

Zitat:
kallevonderecke postete
danke telefonmann für deinen code. leider hilft auch dieser mir nicht weiter, da warenkorb nicht auf methoden con beitrag zugreifen kann. außerdem haben wir dann db_data_objectdoppelt , was ineffektiv ist.
Warum überhaupt sollte "warenkorb" auf Methoden von "beitrag" zugreifen können? Das ist im Sinne der Datenkapselung (ein absolutes, wenn nicht sogar DAS Hauptmerkmal Objektorientierter Programmierung überhaupt) gar nicht erwünscht.
Und außerdem haben wir db_data_object ja nicht wirklich doppelt: Wir haben einen Warenkorb, und einen Beitrag - beide mit einem gemeinsamen "Rumpf", der das Speichern in einer Datenbank kapselt (!).
Ich glaube, Du hast noch nicht ganz verstanden was ich meine... ;-)


43.

hallo zusammen,

1. SIngleton Pattern? leider finde ich nicht razs was das ist. finde nur c und java beispiele die ich nicht verstehe. kann mir jmd weiterhelfen?

2.
> Warum überhaupt sollte "warenkorb" auf Methoden von "beitrag" zugreifen können? Das ist im Sinne der Datenkapselung (ein absolutes, wenn nicht sogar DAS Hauptmerkmal Objektorientierter Programmierung überhaupt) gar nicht erwünscht.

das ist doch nur en bsp. aber es gibt klassen, die im sinne der datenkapselungen bestimmte funktionen übernehmen znd auf die klasse zugeifen müssen die für die db behandlung zuständig ist.
benutze ich nun verschiedene klassen in einem skript, die alle db emthoden nutzen und alle einzeln diese klasse einbinden, ist das nicht ineffekktiv?

kann mir jmd ein tut zum sinnvollen aufbau von php projekten empfehlen. ich merke einfavch dass meine bisherigen konzepte kaum noch aufgehen wenn das projekt größer wird.

bin sehr an eduren konzepten interessiert...

danke

kal


44.

Guten Morgen!

Zitat:
kallevonderecke postete
das ist doch nur en bsp. aber es gibt klassen, die im sinne der datenkapselungen bestimmte funktionen übernehmen znd auf die klasse zugeifen müssen die für die db behandlung zuständig ist.
benutze ich nun verschiedene klassen in einem skript, die alle db emthoden nutzen und alle einzeln diese klasse einbinden, ist das nicht ineffekktiv?
Nein, das ist nicht ineffektiv, denn genau so kann man das machen, ohne auch bei größeren Projekten den Überblick zu verlieren. (Ich hoffe Du meinst erben, wenn Du oben schreibst "Klasse einbinden").

Du fängst dann erst mal so an, daß Du die DB-Klasse implementierst, wo die wichtigsten DB Funktionen drin abgehandelt werden. Ich habe es bei mir z.B. in etwaa so gemacht, daß es in der DB-Klasse eine Variable "$buffer" gibt, in der die eigentlichen Daten liegen. Die DB-Klasse nimmt sich beim Aufruf der Methode "speichern()" die Daten aus $buffer und legt sie in der Datenbank ab. Umgekehrt liest sie die Daten beim Aufruf von "lesen()" aus der Datenbank und legt sie in "$buffer" ab. Der DB-Klasse ist dabei im Prinzip egal, was in "$buffer" drinsteht, sie nimmt es einfach und legt es in der DB ab. Fertig.

So, anschließend schreibst Du deine "Spezialklassen", die alle von der DB-Klasse abgeleitet sein müssen. Die Spezialklasse legt dann das, was sie gerne gespeichert haben möchte, in "$buffer" ab und ruft "parent::speichern()" auf. Damit ist die Arbeit in der Spezialklasse schon erledigt, denn um das Speichern kümmert sich ja nun das DB-Objekt!

Ich habe mir wirklich Mühe gegeben, ich hoffe Du durchschaust nun was ich meine :-)


45.

vielen, vielen dank telan! ich hoffe ich darf deine mühe noch einmal -hoffentlich abschließend- in anspruch nehmen, um nochmal was zu hinterfragen.

ich habe bewusst von 'einbinden' geredet, weil ich mir nicht sicher bin ob man mit 'erben' hier weiter kommt.
was ist denn, wenn ich nicht nur eine dbClass sondern auch eine sessionHandleClass (logged_in? log_out etc.) habe? meine spezialclass kann ja nur eine klasse 'erben'. ich muss also die instanzen von den 'standard klassen' der spezialClass übergeben. dann habe ich aber das problem, dass die methoden von sessionHandleClass nicht auf die dbClass methoden zugreifen können. das müssen sie aber.

also müsste ich spezialClass die instanzen von dbClass und sessionHandleClass übergeben und sessionHandleClass auch nochmal eine instanz von dbClass . ich find das irgendwie zu verschalchtelt doppeltgemoppelt unüberscihtlich...

ist das SIngleton Pattern hier vielleicht die wunderwaffe die ich scuhe?

nochmals vielen dank!

kal


46.

Das Singelton-Pattern lässt sich hier prima einsetzen, ja. Grundsätzlich will ich auch dem lieben Telefonmann ein klein wenig widersprechen: Ich halte es für gar keine gute Idee, die Datenbankfunktionen direkt in die Elternklasse meiner Datenklassen zu implementieren. Dies ist in meinen Augen ein Missbrauch der Vererbung zu Zwecken, die man besser über eine Assoziation gelöst hätte. Ich schlage folgendes vor:

Code:                   In Zwischenablage kopieren (nur IE)
10">

Die Oberklasse Storable ist die Oberklasse für alle Objekte, deren Zustand sich dauerhaft speichern lässt. "Storable" greift seinerseits auf eine Instanz von "DbClass", wo die konkrete Implementierung der Datenbank-Verbindung und -Befehle zu finden ist.

SpecialClass ist von Storable abgeleitet und kann die Methoden "speichern" und "laden" (oder wie auch immer) von Storable nutzen. Diese spezielle "SpecialClass" hält aber außerdem eine Instanz von "SessionClass", um Sessionfunktionen auszuführen.

Sowohl die Instanz von DBClass als auch SessionClass können (sollten) über das Singleton Pattern erzeugt werden.


47.

so hab ich es ja eigenltich auch immer gemacht.

ich hate eine klasse, die verschiedene klassen instantiziert.

erstellte ich eine specialClass für einen bestimmten zweck erbte ich dieses 'storage' class und erweiterte sie nach meinen bedürfnissen. dass man das singleton paatern nennt. wusst ich net.

ich mächte jtzt aber nochmal auf mein eingangstopic zurückkommen: 'auf methoden übergordneter klassen zugreifen '.

das ding ist nämlich, um oimles bsp aufzunehmen, dass SessionClass auf DBClass zugreifen muss.

thats the thing und es scheint die einzige möglichkeit zu sein, SessionClass die instanz von DbClass nocmal zu übergeben bzw. dass SessionClass im konstuktor eine instanz von DbClass bildet.

oder hab ic hschon wieder nichts verstanden?

danke
kal


48.

Nun, nein, das nennt man nun eigentlich nicht Singleton Pattern. Das Singelton Pattern sorgt dafür, dass von einer Klasse nur ein einziges Objekt erzeugt wird.

Vorgehensweise: Deine SessionClass holt sich über eine (selbst definierte) Funktion eine Instanz der DBClass. Diese Funktion gibt aber IMMER diesselbe Instanz der DBClass zurück.


49.

hhmmmm... dann möcht ich nochmal deine schema zitieren

[code][Storable] --- uses ---> [DbClass]
^
/_\
|
|
[SpecialClass] --- uses ---> [SessionClass]
{/code]

das heiist doch: ich hab nen storableClass, die z b im konstuktor DbClass instantisziert (und auch noch andere klassen). dann erbst meine specialClass die sstorableClass und kann daher auf DbClass zugreifen.wenn ich jetzt aber andere klassen einbinde, wie z b SessionClass, und die auf DbClass zugreifen wollen, müssen sie diese, "über eine (selbst definierte) Funktion eine Instanz der DBClass" bilden.

letztlich heisst das doch es wurde zweimal (wenn mehrere andere klassen die dbClass brauchen noc mehr) instanzen von derwselben klasse gebildet.

oweit war ich schon als ich den topic hier eröffnet habe. denn ich will ja grade, dass nur eine instanz gebildet wird. das sessionClass-beispiel ist vielleicht etwas ungünstig. aber wenn ich z b eine klasse habe, die die authentifizierung oder eine bilderverwaltung oder gar ein adressbuch managt, dann brauch ich doch auf jeden fall die DbClass...

danke und gruß

kal


50.

Du hast das Sinlegton-Pattern immernoch nicht verstanden, deswegen hier ein Beispiel:

Code:                   In Zwischenablage kopieren (nur IE)
11">

Obige Funktion liefert immer diesselbe Instanz zurück, es wird also nur eine Instanz erzeugt, egal wie oft man die Funktion aufruft. Also kannst Du die Funktion nach belieben in allen Klassen benutzen.

Schicker ist es bestimmt noch, auch um diese Funktion eine ganze Klasse herumzustricken, aber das ist an sich unnötig.


51.

Zitat:
oimel postete
Das Singelton-Pattern lässt sich hier prima einsetzen, ja. Grundsätzlich will ich auch dem lieben Telefonmann ein klein wenig widersprechen: Ich halte es für gar keine gute Idee, die Datenbankfunktionen direkt in die Elternklasse meiner Datenklassen zu implementieren. Dies ist in meinen Augen ein Missbrauch der Vererbung zu Zwecken, die man besser über eine Assoziation gelöst hätte.
Nun, ich würde eher sagen daß das Geschmackssache ist. Ich entscheide das meist anhand des Speicherbedarfs, und da die DB Klasse fast keine eigenen Attribute hat und um Prinzip nur aus Methoden besteht spricht auch nichts dagegen sie gleich in "Storable" zu lassen. Aber ok, das ist nicht die reine Lehre, und es war ja auch nur als Gedankenanstoß für den OP gedacht. Wenn man es nämlich genau nimmt, ist mein Ansatz eine vereinfachte Version Deines Vorschlags.
Und das Singleton-Pattern ist in einer Sprache wie PHP auch nicht nötig, wenn ich von einer Klasse nur eine Instanz benötige lege ich diese eben zu Beginn des Programms in einer globalen Variable (nichts anderes bewirkt ja static) an und fertig. Ich finde das leichter lesbar. Das ist so eine Unart aus Java, daß man wieder alles in dieses OO-Schema zu pressen versucht... ;-)
Kurzum: In PHP muß ich sowieso noch viele Einschränkungen hinsichtlich der Objektorientierung hinnehmen, dafür "darf" ich mir dann das Leben an anderer Stelle auch etwas vereinfachen.


52.

Neinneinnein, also das Singleton Pattern hat noch weitere Vorteile gegenüber globalen Variablen: So kann ich bei Bedarf entscheiden, doch mehr als eine Instanz zu erzeugen oder auch flexibel je nach Auslastung entscheiden, ob es nicht besser wäre, eine andere Implementierung zu wählen. Außerdem ist das Singleton-Pattern in jedem Fall übersichtlicher als eine globale Variable. Frag da mal Deinen Dozenten ;)


53.

Zitat:
oimel postete
Neinneinnein, also das Singleton Pattern hat noch weitere Vorteile gegenüber globalen Variablen: So kann ich bei Bedarf entscheiden, doch mehr als eine Instanz zu erzeugen oder auch flexibel je nach Auslastung entscheiden, ob es nicht besser wäre, eine andere Implementierung zu wählen.
Wir reden hier aber doch über eine (relativ kleine) browsergesteuerte Anwendung, die ohnehin die meiste Zeit auf Aktionen des Benutzers wartet. Wo willst Du da denn etwas "je nach Auslastung" entscheiden? Ich würde Dir ja Recht geben, sprächen wir hier über einen Mailserver in C++, aber so...

Zitat:
oimel postete
Außerdem ist das Singleton-Pattern in jedem Fall übersichtlicher als eine globale Variable. Frag da mal Deinen Dozenten ;)
Die PHP-Datenbankanwendungen bei uns in der Firma habe ich immer nach diesen Maßgaben entwickelt; bei "echten" Projekten geht es nämlich auch darum, daß ein Programm innerhalb eines straff gesteckten Zeitraums gut funktioniert, im Prinzip egal wie. Frag da mal Deinen Dozenten! ;-)


54.

Zitat:
Telefonmann postete
... bei "echten" Projekten geht es nämlich auch darum, daß ein Programm innerhalb eines straff gesteckten Zeitraums gut funktioniert, im Prinzip egal wie. Frag da mal Deinen Dozenten! ;-)
Ich arbeite seit 5 Jahren an "echten" Projekten. Ich habe Content-Management-Systeme bei Fernsehsendern wegen zu viel Konzeption scheitern sehen und 3D-Software mangels Konzeption den Bach runtergehen. Glaub mir, ich kann Dir ziemlich genau sagen, wann was wo sinnvoll ist. *angeb*


55.

Dann liegen wir "erfahrungsmäßig" ja ziemlich gleichauf - und Du würdest wirklich jede PHP Anwendung komplett OO-Mäßig durchdesignen, mit Singletons etc.? Aus meiner Erfahrung heraus würde ich sagen, daß das für eine Web-Anwendung einfach übers Ziel hinausgeschossen ist. Aber das entscheidet natürlich auch ein Stückweit der "persönliche Programmier-Stil", der bei uns wohl diesbezüglich etwas unterschiedlich ausgeprägt zu sein scheint... ;-)


56.

Ich möchte es mal eher umkehren: Das Open-Source-CMS "Der Dirigent" bietet an sich eine gute Funktionalität. Allerdings ist es fast komplett nicht-objektorientiert aufgebaut und globale Variablen werden intensiv gebraucht. Ich habe bereits nach ein paar Stunden feststellen können, dass es einige Nadelöhre gibt, durch die das System schlecht skalierbar ist. Wegen der Struktur lässt sich da aber nicht mehr viel machen, es sei denn, man programmiert das komplette System neu.

Nun ist dieses CMS in meinen Augen aber noch nichtmal ein großes Projekt, sondern allerhöchstens "mittelgroß". Deshalb: Alles was über einen Formmailer hinausgeht gehört sich NATÜRLICH objektorientiert programmiert.

Ich hatte in der Prüfung fürs Diplom auch einen Prüfer vor mir sitzen, Inhaber des Lehrstuhls für Bildverarbeitung, der hielt grundsätzlich nicht besonders viel von Objektorientierung. Verständlich, denn in der Bildverarbeitung interessieren hauptsächlich Algorithmen, Mathematik und Matrizen als das höchste an Datenkomplexität. Im Web handelt es sich aber meist um Informationssysteme, die einen Teil der realen Welt abbilden: Genau dafür wurde die Objektorientierung geschaffen.


57.

ich bin fest entschlossen, dass jetzt endlich zu checken! also hab ich mal ein kleineres bsp erstellt. wäre sehr nett wenn man mir sagen könnte, ob da jetzt der singleton pattern gedanke hintersteckt bzw. das so ne gute lösung wäre...

Code:                   In Zwischenablage kopieren (nur IE)
12">

vielen vielen dank!
grüße
kal


58.

leider funz tdas ding net! hab versucht es nochmal zu vereinfachen: wozu wird dbInstance eigentlich null gesetzt'? und dann nur wenn dbInstance gleich null ist instantiziert? dann wird es ja jdesmal neu instantisziert ode,r?


generieren.class.php

Code:                   In Zwischenablage kopieren (nur IE)
13">

beispel.php:

Code:                   In Zwischenablage kopieren (nur IE)
14">

weiterhin vielen dank!
kal, der jetzt endlich ins bett geht (ich hass-liebe diese coding nächte!)


59.

- "require" sollte nicht innerhalb von Methoden aufgerufen werden. Klassen innerhalb von Klassen einzubinden macht keinen echten Sinn.
- Für das Singelton-Pattern sollt Du eine eigenständige Funktion schreiben, die von überall aus aufgerufen werden kann, und keine Methode.
- Klassen greifen auf diese externe Funktion zu, UNABHÄNGIG von Vererbungshierarchien.
- Lies mal in der DOku zu "static" nach, das null-Setzen passiert nur beim allerersten Aufruf der Funktion.


60.

> "require" sollte nicht innerhalb von Methoden aufgerufen werden. Klassen innerhalb von Klassen einzubinden macht keinen echten Sinn.

mein template soll ja nur eingebunden werden wen auch die methode dazu aufgerufwn wird. wieso soll ich es denn da woanders einbinden? und wo wäre es besser?


> Für das Singelton-Pattern sollt Du eine eigenständige Funktion schreiben, die von überall aus aufgerufen werden kann, und keine Methode.

hab ich. danke, so funzt es. ich habe es jetzt so gemacht, dass alle klassen, deren methoden häufig die DBClass nutzen, bereits im konstruktor über $this->DbInstance=<createDBInstance() DBClass instantitzieren, schließlich will ich nicht in jeder methode das nochaml machen.


> Klassen greifen auf diese externe Funktion zu, UNABHÄNGIG von Vererbungshierarchien.

das scheint der tick an der sache zu sein, oder?


- Lies mal in der DOku zu "static" nach, das null-Setzen passiert nur beim allerersten Aufruf der Funktion.

das war das erste was ich gemsacht habe, nachem du das erste mal was mit static gepostet hast. ich verstehe aber trotzdem nicht, warum man es nicht so macht:

[CODE]function createDBInstance() {
static $dbInstance;
if (!$dbInstance) $dbInstance = new DBClass();
return $dbInstance;
}php]

bei static $dbInstance = null ist doch gar keine abfrage dabei, ob es nicht schon erstellt ist, sondern wird immer nulll gesetzt. und danach, weil =null, in jedem vfall neu instantiziert. oder heisst static $dbInstance = null: setzte nur null, wenn nicht breits erstelt? das wär mir neu und davon steht auch nichts in der static doku...


ein abschließendes vielen vielen vilen dank! da hab ich was fürs (php-)leben gelernt!

viele grüße

kal


61.

- Klassendefinitionen können immer eingebunden werden, ob man sie benutzt, ist ja noch eine ganz andere Sache.
- Die Zuweisung innerhalb des static-Statements wird nur beim ersten Aufruf der Funktion ausgeführt. Deshalb ist "static $variable=null" korrekt, während man bei "static $variable" implizit davon ausgeht, dass der Standardwert der Variable "nicht gesetzt" ist.


62.

Ich sag's ja: Das Singleton-Pattern macht den Code unleserlich ;-) Aber wie sagte mein Opa schon immer so schön: "Macht watt ihr wollt, nur liegt mir nicht hinterher in den Ohren!" ...


63.

was ist vom diesen beiden ansaätzen zu halten?
zur ersten funktioun: grundsaätzlich halte ich es für effektiver, wenn man die klasse nur einbindet, wenn sie auch gebraucht wird. andernfalls muss der parser doch nur unnötig viel code durchgehen. und einen nachteil kann ich nmicht erkennen.

zur 2. func: solange man nur eine istanz erstellt funzt es. nur wenn man eine zweite klasse instantizieren möchte haut es net mehr hin, weil beides mal in die selbe static variable geschrieben wird. kann an nicht sowas machen wie static $class.$instance...? es ist leider schwer nach &= zu suchen, ich glaube damit könnte man hier weiterkommen. bin das manual zu den punkten Ausdrücke , Operatoren , Kontroll-Strukturen durchgegangen. da gabs leider keine infos dazu. wo kann ich da nachgucken und was ist von dem ansatz zu halten?

Code:                   In Zwischenablage kopieren (nur IE)
15">

danke und grüße

kal


64.

@Telefonmann: Von Unleserlichkeit keine Spur in kalles letztem Post, im Gegenteil. Wenn Dir das "static"-Konstrukt nicht gefällt liegt es vielleicht (wiedermal) eher daran, dass es Dir ungewohnt vorkommt :D

Aber zurück zur Sache: Das ursprüngliche Singleton-Pattern sieht so aus, dass man für jede Art von Objekt eine neue Funktion schreibt. Natürlich kann man das Pattern aber auch in der Form modifizieren, dass es für jede Art von Objekt funktioniert.

Man sollte sich nur darüber im Klaren sein, dass man dann keine Spezialbehandlung für einzelne Klassen mehr durchführen kann. So könnte es ja z.B. bei Datenbankklassen sinnvoll sein, vor dem Erzeugen der Instanz erstmal auszuwählen, welche Parameter und welche konkrete Implementierung verwendet wird, also z.B. so:

Code:                   In Zwischenablage kopieren (nur IE)
16">

Das, was Du als zweites machen willst, würde ich eher als neuen "new"-Operator mit Zusatzfunktionalität bezeichnen und würde das nicht auf Einzelobjekte beschränken. Ich würde es eher so machen:

Code:                   In Zwischenablage kopieren (nur IE)
17">

Damit hast Du zwei Funktionen: "createInstance" funktioniert wie "new", nur mit dem Unterschied, dass die Klassendatei bei Bedarf eingebunden wird. Eine sinnvolle Erweiterung wäre hier allerdings noch, "createInstance" um Parameter für den Konstruktor der Klasse zu erweitern.


65.

hab den spass erweitert in dem sinne dass man die parameter für den konstrukot mit übergegebn kann. dabei ist jedoch das problem, dass wenn man nicht strings und arrays oder objekte gemischt übergeben kann.

das hat mich zu der idee geführt, dass vielleicht eh ganz schick sein könnte, wenn jede mthode immer alle parameter in einem array übergebn bekommen muss. ich finde das macht die sache irgendwie übersichtlicher.

1. was ist davon zu halten
2. wenn nix davon zu halten, wie kann man createInstance so ändern, dass man sowohl strings als aucharrays ond objekte übergeben kann?


Code:                   In Zwischenablage kopieren (nur IE)
18">

gruß

kal


66.

Das kannst du so schon machen. In der Tat habe ich das auch schon öfter gemacht, dass man einfach immer Arrays übergibt. Für den Anwender interessanter wäre aber sicherlich eine Lösung über func_get_args()


67.

habe es sowohl die array nly variante las auch eine variante mit func_get_args()verscuht. beides ist relativ unpraktikabel.
daher binich weiterhin auf der suche nachen einer möglichkeit, die funktion

Code:                   In Zwischenablage kopieren (nur IE)
19">

kompaibel zu array übergaben zu machen. leider find ich keine lösung, slebst mit aufwendigsten schleifen und array funktionnen. weiß jmd weiter?

danke

kal


68.

Du baust ja auch einen falschen Quellcode zusammen, wenn du dir das, was an eval übergeben wird, mal ausgeben lassen würdest, würdest du das sehen.


69.

der vollständghalbar und dass der thread dem recherchierendem später mal hilft jetzt noch mal meine finale vaiante zur lösung des problems. gundsaätzlich ist definiert, dass alle methoden und funktionen immer n ur ein array übergebn bekommen dürfen.


Code:                   In Zwischenablage kopieren (nur IE)
20">

überaöö wo man die jeweiligen klassen dann braucht wird die entsprechende createInstance funktion aufgerufen, die global verfügbar ist. durch static wird kein objekt 2mal instantitiiert.


mfg und ein finales danke an alle die mir geholen haben, bsonders telefonmann und oimel!

kal


Hier gehts zum Orginal Eintrag "auf methoden übergordneter klassen zugreifen" im Forum
 
phpforum.de | Impressum