Meinews.de  


Zurück   Meinews.de > Forum > Newsgroups de.comp.lang.* Forum > Newsgroup de.comp.lang.php.misc
Registrieren FAQ Benutzerliste Kalender Suchen Heutige Beiträge Alle Foren als gelesen markieren

Newsgroup de.comp.lang.php.misc Sonstige Fragen zu Anwendung und Programmierung.

Antwort
 
Themen-Optionen Ansicht
  #11  
Alt 11-16-2009, 12:14 AM
Benjamin Zikarsky
 
Beiträge: n/a
Standard Re: Designfrage OOP

Stefan Froehlich schrieb:
> Na, dann macht man halt:
>
> | $h_obj = cHauptklasse::getInstance();
> | $u_obj = new cUnterklasse($h_obj, 1234);
>
> ...und schon hat man wieder ein Objekt ausserhalb der Hauptklasse
> erzeugt.
>



Nicht, wenn Du eine Prüfung im Konstruktor der Unterklasse hast,
schematisch so:

class cUnterklasse
{
public function __construct(cHauptklasse $c)
{
if (!$c->isAllowedUnterklasse($this)) {
throw new Exception('...');
}
}
}

Damit kannst du dann eine Art "Multiton" in Abhängigkeit der Oberklasse
realisieren.

Im Fall der Fälle setzt Du den Konstruktor noch auf "final", und der
Erbfall ist auch gesichert.


HTH,
Benjamin
Mit Zitat antworten
Alt Today
Advertising
Google Adsense
 
This advertising will not be shown
in this way to registered members.
Register your free account today
and become a member on
Meinews.de
Standard Sponsored Links

  #12  
Alt 11-16-2009, 12:51 AM
Andreas Born
 
Beiträge: n/a
Standard Re: Designfrage OOP

Markus Malkusch wrote:
> Andreas Born:
>
>> Ich einigen Sprachen ist es mittlerweile üblich, auf öffentliche
>> Eigenschaften nur mittels Getter und Setter zuzugreifen, auf diese
>> Weise kann man bestimmen, ob eine Eigenschaft nur lesbar, nur
>> schreibbar, oder beides ist.

>
> Hä? Keiner hindert Dich daran das in PHP genauso zu handhaben.


Naja, es gibt keine echten Getter und Setter in PHP. Nur Hilfskontrukte
über Funktionen oder eben __get() und __set().

> Ich mache das auch noch in Zeiten von __get() und __set() genauso. Ein
> Attribut als public zu deklarieren kommt mir nicht in die Tüte.
>
>> In PHP ist dies nur mittels "Overloading" möglich.

>
> Ich versteh g'rad nicht was Überladung damit zu tun haben soll.


Die PHP-Doku bezeichnet __get() und __set() als "Member Overloading",
was m.E. der falsche Ausdruck dafür ist. Das schrieb ich ja auch.

>> Der Wert einer Readonly-Eigenschaft wird in der Regel bei der
>> Objekterstellung festgelegt.

>
> [..]
>
>> Sobald es sich bei $member aber um eine Objektinstanz mit eigenen
>> readonly-Eigenschaften handelt, würde die Möglichkeit, $member von
>> außen erstellen zu können, den readonly-Schutz konterkarieren.

>
> Das sehe ich nicht so (oder wir verstehen uns falsch). Es geht Dir
> doch um den unveränderlichen Zustand eines Objektgraphen.


Auch, aber nicht nur. (s.u.)

> Der soll sobald Du das Wurzelobjekt erstellt hast feststehen.


Genau. Und dieses Wurzelobjekt soll das einzige Objekt sein, das diesen
Graphen erstellen darf..

> Wenn Du danach also außerhalb dieses Graphen irgendwelche Teilobjekte
> erstellst, interessiert es den Graphen herzlich wenig, da Du (wegen
> fehlenden Settern) keine Möglichkeit hast da irgendwas auszutauschen.
>
> Also als konkretes Beispiel:

[...]

Okay, den Graphen selber interessiert es nicht, richtig. Das habe ich
auch bereits im Griff.

Es geht mir darum, daß eben diese Teilobjekte nicht von außerhalb des
Wurzelobjektes erstellbar sein sollten.

Schematisch: Angenommen, ein solches Teilobjekt stellt einen Datensatz
dar und bietet die Möglichkeit an, diesen Datensatz zu ändern oder zu
löschen. Das Wurzelobjekt stellt nun eine Aufzählung solcher Datensätze
bereit, inklusiver der Information ob dieser gelöscht werden darf. Den
Benutzer braucht das nicht zu interessieren, denn er kann ja einfach das
Teilobjekt des Graphen selbst erstellen und dann jeden beliebigen
Datensatz löschen. Das Teilobjekt selbst ist nicht in der Lage
festzustellen, ob die repräsentierte Datei gelöscht werden darf. Das
genau legt das Wurzelobjekt fest.

Aber vielleicht ist es eine Frage des Designs, daß man bestimmte
Funktionalitäten einfach nicht in Objekte legen darf, die von außen
erstellbar sind. Macht die Sache aber unleserlicher:

Beabsichtigt:

$graph = new graph();
$graph->getChild($id)->delete();

Problem: (das soll nicht möglich sein)
$child = new child($id);
$child->delete();


Besser (?)

$graph = new graph();
$graph->deleteChild($graph->getChild());


Nun könnte es sich bei den Childs aber um verschiedene Objekttypen
handeln, die gemeinsam haben, daß sie alle ein bestimmtes Interface
implementieren, durch das z.B. die Methode delete() vorgegeben wird.
Gegen die zweite Variante spricht also, daß das Wurzelobjekt u.u.
garnicht weiß, wie das Childobjekt zu löschen ist.

Möglichkeiten gibts ne Menge, das zu lösen. Aber anscheinend ist es vom
Design her recht untypisch.

Eine variante mittels protected:

interface IDelete {
public function delete();
protected function __construct($id,$deletable);
}
abstract class cPrototype {
protected function createChild($className, $id, $deletable) {
return new $className($id, $deletable);
}
}
class cWurzel extends cPrototype {
private $childs;
public function getChild($id) {
reutrn $this->childs[$id];
}
public __construct() {
$this->childs = array();
#.... füttern
$this->childs['bsp'] = self::createChild('cChildA','bsp',true);
$this->childs['exp'] = self::createChild('cChildB','exp',true);
}
}
class cChildA extends cPrototype implements IDelete {
private $id = null;
private $deletable = false;
protected function __construct($id, $deletable) {
$this->id = $id;
$this->deletable = $deletable;
}
public function delete() {
if ($this->deletable) {
# löschen...
} else trigger_error('not allowed', E_USER_ERROR);
}
}
class cChildB extends cPrototype implements IDelete {
/* similar */
}


Viele Grüße,
Andreas

Mit Zitat antworten
  #13  
Alt 11-16-2009, 12:59 AM
Claus Reibenstein
 
Beiträge: n/a
Standard Re: Designfrage OOP

Andreas Born schrieb:

> Naja, es gibt keine echten Getter und Setter in PHP.


Wie bitte?

> Nur Hilfskontrukte
> über Funktionen oder eben __get() und __set().


Kann ich nicht nachvollziehen. Meine Klassen haben ganz normale get- und
set-Methoden, keine "Hilfskonstrukte über Funktionen" (was immer Du
damit meinst), kein __get() oder __set().

Gruß. Claus
Mit Zitat antworten
  #14  
Alt 11-16-2009, 01:38 AM
Andreas Born
 
Beiträge: n/a
Standard Re: Designfrage OOP

Claus Reibenstein wrote:
> Andreas Born schrieb:
>
>> Naja, es gibt keine echten Getter und Setter in PHP.

>
> Wie bitte?
>
>> Nur Hilfskontrukte über Funktionen oder eben __get() und __set().

>
> Kann ich nicht nachvollziehen. Meine Klassen haben ganz normale get-
> und set-Methoden, keine "Hilfskonstrukte über Funktionen" (was immer
> Du damit meinst), kein __get() oder __set().


Deine set-Methode ist (vermutlich) nichts anderes als eine normale
Funktion.

class cObject {
private $property;
public function setProperty($value) { $this->property = $value }
public function getProperty() { return $this->property; }
}
$object = new cObject();
$object->setProperty('hallo welt');
echo $object->getProperty();

Ein echter Setter wäre zwar auch eine (interne) Methode, die aber durch
eine Zuweisung aufgerufen wird. Schematisch, weil es in php das eben
*nicht* gibt;

class cObject {
private $property;
public set property($value) { $this->property = $value }
public get property() { return $this->property; }
}
$object = new cObject();
$object->property = 'hallo welt';
echo $object->property;

Das ist realisierbar, aber eben nur mittels __get() und __set().

Ich unterscheide grunsdätzlich zwischen methoden und eigenschaften. Eine
Methode wird wie eine funktion aufgerufen [$obj->method()] während eine
Eigenschaft wie eine Variable verwendet wird [$obj->property = ...].

Natürlich steht es jedem frei, nur mit Funktionen zu arbeiten und ggf.
anhand eines vorangestellten "get" oder "set" getter- und
setter-funktionalität optisch davon abzugrenzen, aber echte Getter und
Setter sind das in meinen Augen nicht.

Ein Setter ist meiner Auffassung nach eine interne Methode, deren Aufruf
durch eine Variablenzuweisung erfolgt, entsprechend wird ein Getter
durch den lesenden Zugriff auf die Variable ausgelöst. Getter und Setter
sind nicht extern aufrufbar und grenzen sich dadurch von normalen
Funktionen ab. Ansonsten könnte man es auch einfach "Funktion" oder
"Methode" nennen. ;-)


Viele Grüße,
Andreas

Mit Zitat antworten
  #15  
Alt 11-16-2009, 03:28 AM
Niels Braczek
 
Beiträge: n/a
Standard Re: Designfrage OOP

Andreas Born schrieb:

> Ich unterscheide grunsdätzlich zwischen methoden und eigenschaften. Eine
> Methode wird wie eine funktion aufgerufen [$obj->method()] während eine
> Eigenschaft wie eine Variable verwendet wird [$obj->property = ...].


Ich mache diese Unterscheidung auch - alle Eigenschaften sind private
oder maximal protected, falls ich doch mal den Rückschritt zur Vererbung
mache.

> Natürlich steht es jedem frei, nur mit Funktionen zu arbeiten und ggf.
> anhand eines vorangestellten "get" oder "set" getter- und
> setter-funktionalität optisch davon abzugrenzen, aber echte Getter und
> Setter sind das in meinen Augen nicht.


Mag sein, dass das auf einer theoretischen Ebene keine Getter oder
Setter sind - in PHP aber sind getX()- und setX()-Methoden genau das,
was man Getter und Setter nennt.

> Ein Setter ist meiner Auffassung nach eine interne Methode, deren Aufruf
> durch eine Variablenzuweisung erfolgt, entsprechend wird ein Getter
> durch den lesenden Zugriff auf die Variable ausgelöst. Getter und Setter
> sind nicht extern aufrufbar und grenzen sich dadurch von normalen
> Funktionen ab. Ansonsten könnte man es auch einfach "Funktion" oder
> "Methode" nennen. ;-)


Das kannst du mit __get() und __set() und ein wenig Reflection
nachbilden. Allerdings halte ich das für unpraktisch (schlechten Stil),
weil man einer Zuweisung nicht ansieht, dass der Wert verändert werden
könnte.

MfG
Niels

--
| http://www.kolleg.de · Das Portal der Kollegs in Deutschland |
| http://www.bsds.de · BSDS Braczek Software- und DatenSysteme |
| Webdesign · Webhosting · e-Commerce · Joomla! Content Management |
------------------------------------------------------------------
Mit Zitat antworten
  #16  
Alt 11-16-2009, 09:01 AM
Knut Kohl
 
Beiträge: n/a
Standard Re: Designfrage OOP

Hallo,

Andreas Born schrieb am 16.11.2009 in de.comp.lang.php.misc:

> Es geht mir darum, daß eben diese Teilobjekte nicht von außerhalb des
> Wurzelobjektes erstellbar sein sollten.


> Schematisch: Angenommen, ein solches Teilobjekt stellt einen Datensatz
> dar und bietet die Möglichkeit an, diesen Datensatz zu ändern oder zu
> löschen. Das Wurzelobjekt stellt nun eine Aufzählung solcher Datensätze
> bereit, inklusiver der Information ob dieser gelöscht werden darf.


Damit habe ich ein Problem. Für mich hat ein Objekt genau eine Aufgabe
zu leisten, unabhängig vom der "Einsatz-Umgebung".
Wenn ein Objekt also eine Aufagbe (Löschen) ausführen soll, soll es sich
ggf. die Info (Deletable) spätestens dafür in dem Moment besorgen
können.

> Den
> Benutzer braucht das nicht zu interessieren, denn er kann ja einfach das
> Teilobjekt des Graphen selbst erstellen und dann jeden beliebigen
> Datensatz löschen. Das Teilobjekt selbst ist nicht in der Lage
> festzustellen, ob die repräsentierte Datei gelöscht werden darf. Das
> genau legt das Wurzelobjekt fest.


Dann würde ich das trotzdem durch Injection lösen.

Die Idee: Das Child kann nur durch Rückfrage beim Owner herausfinden, ob
es löschbar ist. Selbst wenn ein Child "losgelöst" erstellt wird, muss
ein dabei angegebener Owner die Deletable-Frage mit FALSE beantworten,
da ein Child NUR durch __construct Mitglied einer Wurzel werden kann und
auch KEINE andere Wurzel dieses Child enthalten kann.

interface IDelete {
public function delete();
protected function __construct(cPrototype $owner, $id);
}

abstract class cPrototype {
// static for self::
protected static function createChild($className, $id) {
return new $className($this, $id);
}
public function isDeletable() {
return FALSE;
}
}

class cWurzel extends cPrototype {
private $childs;
public function getChild($id) {
reutrn $this->childs[$id];
}
public __construct() {
$this->childs = array();
#.... füttern
$this->childs['bsp'] = self::createChild('cChildA','bsp');
$this->childs['exp'] = self::createChild('cChildB','exp');
}
public function isDeletable($child) {
$return = FALSE;
// Child dieses Objektes?
if (array_search($child, $this->childs)) {
// Ermitteln des Status, der vorher im __construct
// ja auch irgendwie ermittelt worden sein muss :-)
}
return $return;
}
}

class cChildA extends cPrototype implements IDelete {
private $id = null;
private $owner = NULL;
protected function __construct(cPrototype $owner, $id) {
$this->owner = $owner;
$this->id = $id;
}
public function delete() {
if ($this->owner->isDeletable($this)) {
# löschen...
} else trigger_error('not allowed', E_USER_ERROR);
}
}

Knut

--
http://es-f.com
Web frontend for esniper, the console application for sniping eBay auctions.
Mit Zitat antworten
  #17  
Alt 11-16-2009, 09:08 AM
Claus Reibenstein
 
Beiträge: n/a
Standard Re: Designfrage OOP

Andreas Born schrieb:

> Claus Reibenstein wrote:
>
>> Andreas Born schrieb:
>>
>>> Naja, es gibt keine echten Getter und Setter in PHP.

>>
>> Wie bitte?
>>
>>> Nur Hilfskontrukte über Funktionen oder eben __get() und __set().

>>
>> Kann ich nicht nachvollziehen. Meine Klassen haben ganz normale get-
>> und set-Methoden, keine "Hilfskonstrukte über Funktionen" (was immer
>> Du damit meinst), kein __get() oder __set().

>
> Deine set-Methode ist (vermutlich) nichts anderes als eine normale
> Funktion.
>
> class cObject {
> private $property;
> public function setProperty($value) { $this->property = $value }
> public function getProperty() { return $this->property; }
> }


Solche Funktionen heißen Methoden. Getter und Setter _sind_ Methoden und
sind genau so definiert. Eine andere Definition ist mir nicht bekannt.

> $object = new cObject();
> $object->setProperty('hallo welt');
> echo $object->getProperty();


Das ist der übliche Weg.

> Ein echter Setter wäre zwar auch eine (interne) Methode, die aber durch
> eine Zuweisung aufgerufen wird. Schematisch, weil es in php das eben
> *nicht* gibt;
>
> class cObject {
> private $property;
> public set property($value) { $this->property = $value }
> public get property() { return $this->property; }
> }
> $object = new cObject();
> $object->property = 'hallo welt';
> echo $object->property;


Hier allerdings bekomme ich Bauchschmerzen. Diese Zuweisung sieht aus
wie eine direkte Zuweisung an eine Eigenschaft, ist aber keine. So etwas
behagt mir gar nicht.

Welche (mir offensichtlich unbekannte) OO-Sprache realisiert das so? PHP
nicht, das wissen wir schon. Java und C++ auch nicht.

In C++ kann man zwar per Operator Overloading so etwas Ähnliches
basteln, aber als Setter würde ich das trotzdem nicht bezeichnen.

> Ich unterscheide grunsdätzlich zwischen methoden und eigenschaften. Eine
> Methode wird wie eine funktion aufgerufen [$obj->method()] während eine
> Eigenschaft wie eine Variable verwendet wird [$obj->property = ...].


Genau das ist der Punkt: Getter und Setter sind Methoden und werden auch
genau so aufgerufen. Eigenschaften, die direkt verändert werden können
(was man normalerweise vermeiden sollte), werden per Zuweisung direkt
geändert.

Eine Anweisung, die wie eine normale Zuweisung aussieht, aber keine ist,
sondern intern einen Setter aufruft, ist mir jedoch mehr als suspekt, da
man ihr ihre tatsächlichen Eigenschaften nicht mehr ansieht.

Welchen Wert hat eigentlich Deine Pseudo-Zuweisung? Nach Deinem
schematischen Beispiel keinen, da kein return-Wert angegeben ist, womit
Mehrfach-Zuweisungen im Stile von

$obj1->x = $obj2->y = $obj3->z = ...

schon mal nicht möglich sind :-)

Gut, das lässt sich noch hinbiegen, indem man den Settern einen
entsprechenden return-Wert verpasst.

Meine Setter hingegen liefern idR eine Referenz auf das Objekt zurück
(oder null, falls etwas schief läuft). Damit sind so hübsche
Konstuktionen möglich wie

$obj -> setx(...) -> sety(...) -> setz(...);

Wie realisiere ich so etwas mit Deiner Pseudo-Zuweisung?

> Natürlich steht es jedem frei, nur mit Funktionen zu arbeiten und ggf.
> anhand eines vorangestellten "get" oder "set" getter- und
> setter-funktionalität optisch davon abzugrenzen, aber echte Getter und
> Setter sind das in meinen Augen nicht.


In diesem Punkt haben wir offensichtlich gänzlich unterschiedlichen
Ansichten.

Gruß. Claus
Mit Zitat antworten
  #18  
Alt 11-16-2009, 09:46 AM
Christoph Herrmann
 
Beiträge: n/a
Standard Re: Designfrage OOP

Claus Reibenstein schrieb:
> Welche (mir offensichtlich unbekannte) OO-Sprache realisiert das so? PHP
> nicht, das wissen wir schon. Java und C++ auch nicht.


C# und Ruby machen es so und das finde ich eine der Stärken dieser
Sprachen. Man kann Eigenschaften einfach setzen und nutzen wie lokale
Variablen des gleichen Datentyps auch und muss sich nicht durch die
Methoden kämpfen.

Dass ein public Zugriff vorgespielt wird ist kein Problem, denn ein
Entwickler dieser Sprachen weiss in der Regel dass bei solchen Zugriffen
Methoden im Hintergrund sein könnten.

--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Mit Zitat antworten
  #19  
Alt 11-16-2009, 10:19 AM
Stefan Froehlich
 
Beiträge: n/a
Standard Re: Designfrage OOP

On Mon, 16 Nov 2009 10:46:27 Christoph Herrmann wrote:
> Claus Reibenstein schrieb:
> > Welche (mir offensichtlich unbekannte) OO-Sprache realisiert das
> > so? PHP nicht, das wissen wir schon. Java und C++ auch nicht.


> C# und Ruby machen es so und das finde ich eine der Stärken dieser
> Sprachen. Man kann Eigenschaften einfach setzen und nutzen wie
> lokale Variablen des gleichen Datentyps auch


Das ist, wie vieles, eine Geschmacksfrage. Wenn nach:

| $obj->a = $a;
| $a = $obj->a;

in $a nicht mehr zwingend der selbe Wert enthalten sein muss, wie
zuvor, dann empfinde ich das als irritierend. Bei Methoden rechne
ich alleine durch ihre Syntax ganz grundsaetzlich damit.

> Dass ein public Zugriff vorgespielt wird ist kein Problem, denn
> ein Entwickler dieser Sprachen weiss in der Regel dass bei solchen
> Zugriffen Methoden im Hintergrund sein könnten.


Ich persoenlich finde halt, dass dann auch der Sinn der Sache
verloren geht, naemlich die Unterscheidung zwischen Zuweisungen und
Funktionsaufrufen. Es gibt dann nur noch "Aufrufe", hinter denen
immer Methoden stecken (koennen), ob nun mit oder ohne Klammern.

Servus,
Stefan

--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Gelassen und doch gebissen?! Stefan - Trost in den Stunden des Zorns.
(Sloganizer)
Mit Zitat antworten
  #20  
Alt 11-16-2009, 10:23 AM
Stefan Froehlich
 
Beiträge: n/a
Standard Re: Designfrage OOP

On Mon, 16 Nov 2009 10:08:16 Claus Reibenstein wrote:
> Welchen Wert hat eigentlich Deine Pseudo-Zuweisung? Nach Deinem
> schematischen Beispiel keinen, da kein return-Wert angegeben ist, womit
> Mehrfach-Zuweisungen im Stile von
>
> $obj1->x = $obj2->y = $obj3->z = ...


> schon mal nicht möglich sind :-)


> Gut, das lässt sich noch hinbiegen, indem man den Settern einen
> entsprechenden return-Wert verpasst.


Das wird man im Regelfall wohl auch tun, so wie Du selbst ja auch:

> Meine Setter hingegen liefern idR eine Referenz auf das Objekt zurück
> (oder null, falls etwas schief läuft).


....die entsprechenden Konventionen befolgst. Aber gerade das macht
IMHO deutlich, dass sich die beiden Zugriffsarten primaer durch ihre
Syntax unterscheiden: Ich kann Methoden schreiben, die Properties
abbilden, und ich kann mit dem Zugriff auf Properties Methoden
aufrufen.

Eventuell war es ja von Anfang an ein Fehler, die Konzepte
"Variable" und "Funktion" einfach so 1:1 auf Objekte zu uebertragen,
wenn man sie dort dann (beinahe - das gilt natuerlich nicht mehr
fuer Methoden mit mehr als einem Argument) bis zur
Ununterscheidbarkeit aufweicht.

Servus,
Stefan

--
http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich
Offizieller Erstbesucher(TM) von mmeike

Erfrischend natürlich - Stefan: waschen, welch warmes Verlangen!
(Sloganizer)
Mit Zitat antworten
 
Antwort


Themen-Optionen
Ansicht

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen
Es ist dir nicht erlaubt, auf Beiträge zu antworten
Es ist dir nicht erlaubt, Anhänge anzufügen
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten

vB Code ist An
Smileys sind An
[IMG] Code ist An
HTML-Code ist Aus

Ähnliche Themen
Thema Erstellt von Forum Antworten Letzter Beitrag
Designfrage Konrad Schiemert Newsgroup microsoft.public.de.vc 2 11-11-2009 11:00 AM
Designfrage Bernhard Newsgroup microsoft.public.de.german.entwickler.dotnet.asp 2 03-26-2009 05:09 PM
Designfrage Norbert Stellberg Newsgroup de.comp.lang.delphi.misc 29 02-10-2009 07:55 AM
Designfrage Tobias Nissen Newsgroup de.comp.os.unix.programming 12 03-12-2008 06:55 PM
Designfrage Uwe Ziegenhagen Newsgroup de.comp.lang.java 17 09-19-2007 12:26 PM


Alle Zeitangaben in WEZ. Es ist jetzt 11:38 PM Uhr.



Powered by: vBulletin Version 3.6.7 (Deutsch)
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Forum SEO by Zoints