PHP objects and public/private methods

Giorgos Keramidas keramida at ceid.upatras.gr
Tue Sep 4 16:59:18 EEST 2007


On 2007-09-04 14:40, Θοδωρής Λύτρας <thlytras at gmail.com> wrote:
>Στις Τρίτη 04 Σεπτέμβριος 2007 13:37, ο/η Christos Ricudis έγραψε:
>> GENIKA milwntas, yparxoun kai protected methods, poy mporoyn na
>> klh8oun apo sub-classes ths class sthn opoia anhkoun, alla oxi apo
>> classes xwris syggenikh sxesh.
>>
>> An xreiazesai na dhlwseis mia method san kati pou den einai oute
>> public oute protected, tote apla exeis kanei lan8asmeno OO design.
>> Rethink your objects.
>
> Χμμ... πολύ σωστό ακούγεται ως αρχή, αλλά αν δεν κάνω λάθος η απάντηση
> υπονοεί οτι όλα τα αντικείμενα ενός *λειτουργικού συνόλου* θα πρέπει
> να έχουν συγγενική σχέση μεταξύ τους. Ισχύει κάτι τέτοιο?

Οχι απαραίτητα.  Οι επιλογές που έχει ένας object-oriented designer
είναι τουλάχιστον οι εξής:

    * object interface

    * public/protected methods/data

Δύο unrelated objects μπορούν άνετα να στέλνουν "messages" το ένα στο
άλλο, μέσω ενός καλά ορισμένου "interface".

> Το άμεσο παράδειγμα που μου έρχεται στο μυαλό είναι το ίδιο το DOM
> όπου σύμφωνα με την τεκμηρίωση της PHP (http://de.php.net/dom) δεν
> έχουν όλες οι κλάσεις συγγενική σχέση μεταξύ τους.  Για παράδειγμα η
> κλάση DOMNodeList δεν έχει σχέση με τη DOMNode.  Όμως περιέχει σαν
> properties της αντικείμενα που προέρχονται από τη βασική κλάση
> DOMNode.

Το PHP δεν είναι κι ότι καλύτερο από πλευράς OO abstraction/design, αλλά
δεν βλέπω γιατί μπερδεύεσαι.  Το γεγονός ότι ένα DOMNodeList "περιέχει"
άλλα αντικείμενα δε σημαίνει ότι το ίδιο το DOMNodeList υποστηρίζει τα
methods των εμπεριεχόμενων αντικειμένων.

Για παράδειγμα, από όσο ξέρω μπορείς να καλέσεις την item() method ενός
DOMNodeList:

    DOMNodeList->item(index);

αλλά το ίδιο το DOMNodeList object δεν έχει, για παράδειγμα, method με
όνομα cloneNode(), οπότε το παρακάτω είναι λάθος:

    DOMNodeList->cloneNode();

> Αυτό περιγράφει και το δικό μου πρόβλημα. Ας επεκταθώ λίγο
> περισσότερο: έχω μια κλάση που ας την ονομάσουμε MyGroup, και μια άλλη
> που θα την πούμε MyElement.  Κάθε αντικείμενο MyGroup έχει ως
> properties του είτε αντικείμενα MyElement, είτε άλλα αντικείμενα
> MyGroup, κατά τρόπο ώστε να προκύπτει μια δενδροειδής δομή.
>
> Η μέθοδος που θέλω να φτιάξω ανήκει στην κλάση MyGroup και στόχος της
> είναι να διατρέξει ένα αρχείο xml και να φτιάξει την αντίστοιχη
> δενδροειδή δομή αντικειμένων.  Αυτή με τη σειρά της καλεί μια δεύτερη
> μέθοδο στην κλάση MyElement η οποία δέχεται έναν κόμβο του XML αρχείου
> και φτιάχνει το αντίστοιχο αντικείμενο.  Σωστά δεν ακούγεται ως εδώ?
>
> Το θέμα όμως είναι οτι η δεύτερη μέθοδος (στην κλάση MyElement) δεν
> έχει νόημα να κληθεί παρά μόνο από την πρώτη μέθοδο (της κλάσης
> MyGroup).  Οι δύο κλάσεις δεν έχουν συγγενική σχέση.

Το MyElement class μπορεί άνετα να έχει μια function με όνομα:

    MyElement->cloneXMLNode();

Αυτή η μέθοδος μπορεί να θεωρηθεί "μέρος του XML interface ενός
MyElement object".  Το γεγονός ότι σήμερα δε μπορείς να σκεφτείς κάποια
άλλη χρήση της MyElement::cloneXMLNode() πέρα από την κλήση που
προέρχεται από το MyGroup class, δεν σημαίνει κάτι.  Το "XML interface
των MyElement objects" θα εξακολουθήσει να είναι "XML interface των
MyElement objects" ακόμα κι αν αργότερα φτιάξεις ένα διαφορετικό
"container class" από το MyGroup.

> Είναι όντως λανθασμένος ο σχεδιασμός των αντικειμένων μου? Πως θα
> έπρεπε να το έχω φτιάξει? Υποθέτω η περίπτωση που περιγράφω πρέπει να
> απαντάται συχνά στον προγραμματισμό (δηλ. αντικείμενο που περιέχει
> άλλα αντικείμενα), έτσι δεν είναι?

Ναι, φυσικά...

http://en.wikipedia.org/wiki/Composite_pattern
http://en.wikipedia.org/wiki/Aggregate_pattern
http://en.wikipedia.org/wiki/Collection_%28computing%29
http://en.wikipedia.org/wiki/Collection_class




More information about the Linux-greek-users mailing list