2009-08-11 13 views

Odpowiedz

4

Zwykle metody te są przydatne, gdy komunikuje się z interfejsem API innej firmy lub gdy struktura metody/elementów jest niejasna.

Załóżmy, że piszesz ogólne opakowanie XML-RPC. Ponieważ nie znasz dostępnych metod przed pobraniem pliku WDL, warto użyć przeciążenia.

Następnie, zamiast pisać, co następuje:

$xmlrpc->call_method('DoSomething', array($arg1, $arg2)); 

Można użyć:

$xmlrpc->DoSomething($arg1, $arg2); 

który składni bardziej naturalny.


Można również użyć przeciążania elementów w taki sam sposób jak przeciążanie metod dla obiektów zmiennych.

Jedna rzecz, na którą chcesz zwrócić uwagę: ogranicz jej użycie tylko do obiektów o zmiennej strukturze lub używaj jej tylko do skrótów syntaktycznych do modułów pobierających i ustawiających. To ma sens, aby utrzymać pobierające i ustawiające w swojej klasie na indywidualne logikę biznesową w wielu metod, ale nie ma nic złego w stosowaniu go jako skrót:

class ShortcutDemo { 
    function &__get($name) { 
    // Usually you want to make sure the method 
    // exists using method_exists, but for sake 
    // of simplicity of this demo, I will omit 
    // that logic. 
    return call_user_method('get'.$name, $this); 
    } 

    function __set($name, &$value) { 
    return call_user_method('set'.$name, $this, $value); 
    } 

    private $_Name; 

    function &getName() { return $this->_Name; } 
    function setName(&$value) { $this->_Name = $value; } 
} 

ten sposób można kontynuować przy użyciu pobierające i ustawiające, aby potwierdzić i ustawić swoje dane, i nadal używać skrótów składniowych, takich jak:

$shortcut->Name = 'Hello'; 
0

Inną metodą, że Andrew nie wspominając (lub nie wspomniano w momencie pisania) jest pozbycie pobierające i ustawiające. Zamiast zadeklarować każdą setter i getter tak:

$obj->setName("Chacha"); 
$obj->setRep(10000000000000000000000); 

Można zamiast po prostu zrobić

$obj->Name = "chacha"; 
$obj->Rep = 100000000000000000; 

Druga metoda jest bardziej naturalny.

Magiczne metody w zasadzie dalsza myśl o programowaniu zorientowanym obiektowo, a idea, że ​​sposób realizacji pracy nie powinna mieć znaczenia dla świata zewnętrznego. Dzięki Magic Methods pozwala przechowywać twoje zmienne w dowolny sposób i pozwolić innym klasom ustawić je w naturalny sposób.

Przykład: Mogłem przechowywać wszystkie preferencje konta mojego użytkownika w pojedynczej tablicy, co ułatwiłoby iterację w celu przekazania wszystkiego do sesji.

Gdybym nie użył w tym celu metody magicznej, musiałbym albo zrobić kilka zestawów albo uzyskać, co oznacza napisanie większej ilości kodu, albo pozwolić na bezpośredni dostęp do tablicy, co ujawnia implementację, więc nie może iść i zmienić go później.

Zamiast tego, używając Magic Methods, po prostu ustawiam zmienną regularnie i zajmuję się nią wewnętrznie.

+0

Chociaż nie pozbyłbym się jeszcze porywaczy i seterów. Wiele metod zawierających reguły biznesowe dla poszczególnych właściwości jest zwykle łatwiejsze do utrzymania i debugowania niż jedna wielka metoda zawierająca wszystkie reguły biznesowe dla wszystkich właściwości. Po prostu użyłbym '__get()' i '__set()' dla skrótu do wywołania 'getX',' setX'. Przeciążanie obiektów należy przechowywać tylko dla obiektów o zmiennej strukturze. –

+0

Przeczytaj moją zaktualizowaną wersję. –

+0

Jednak to nie działa tak jak C# Get/Set Property. Przynajmniej nie tak elastyczne, jeśli chcesz zweryfikować lub sprawdzić, co jest ustawione. – Extrakun

0

Można go używać w przypadkach, gdy klasa ma złożone reguły dotyczące isset i unset. Na przykład klasa zawierająca zmienną $ a może być tablicą obiektów lub innych zasobów, a gdy jest wyłączona, musi wykonywać inne funkcje.

Chociaż nie jestem pewien, dlaczego pozwalają na dodanie nowej właściwości i pobieranie własności nieprywatnej, ale można jej użyć do zmiany stanu wewnętrznego obiektu przez wywołanie innego kodu w zależności od nazwy ustawiono zmienną właściwości/członka.

W niektórych przypadkach ta przypomina operator przeciążenie w C++

0

wiadomość spedycja, gdy masz skomponowanych lub zagregowane obiektach gdzie polimorfizm nie jest rozwiązaniem (powiedzmy, że używasz klasy biblioteki nie można kontrolować).

<?php 

// Class A is final, so we can't make subclasses. 
final class A 
{ 
    public function hello($callback) 
    { 
    echo call_user_func($callback, 'hello world'); 
    } 
} 

// so instead, we make a wrapper class that will take an instance 
// of A as an aggregate 
class B 
{ 
    private $a; 

    public function __construct(A $a) 
    { 
    $this->a = $a; 
    } 

    // this mimics inheritance on the aggregate object 
    // method calls are automatically forwarded to instance of A 
    // if they are valid 
    public function __call($method, $args) 
    { 
    if (method_exists($this->a, $method)) 
    { 
     return call_user_func_array(array($this->a, $method), $args); 
    } 
    throw new Exception("Method [$method] not found."); 
    } 
} 

class C extends B 
{ 
    // This mimics overriding an "inherited" method 
    public function hello($callback) 
    { 
    echo call_user_func($callback, 'bonjour le monde'); 
    } 
} 

$a = new A; 

$b = new B($a); 
$c = new C($a); 

$b->hello('strtoupper'); 
$c->hello('strtoupper'); 
0

Ta funkcja jest faktycznie what object oriented programming is all about, w umyśle jego wynalazca Alan Kay: Przedmioty wysyłania wiadomości siebie i potencjalnie reagowania na wszelkiego rodzaju wiadomości. Metody ustalone w czasie kompilacji są ograniczoną (ale także bardziej wydajną) implementacją tej koncepcji. W tym miejscu słynny cytat Kay "wymyśliłem pojęcie zorientowane na obiekt i mogę powiedzieć, że C++ nie było tym, o czym myślałem". pochodzi z.

Zasadniczo, pozwalając obiektom reagować na wywołania metod bez odpowiedniej metody ustalonej w czasie kompilacji implementuje tę oryginalną, szerszą definicję orientacji obiektowej. Większość nowoczesnych "dynamicznych" języków obsługuje je w takiej czy innej formie.

Jeśli chodzi o to, na czym to służy: spójrz na Groovy's Builders, aby dać dobry przykład. Zasadniczo pozwala to na bardzo zwartą składnię o niskiej redundancji poprzez zamianę samych nazw metod na dane.

0

Jedną z metod, która jest nieco bardziej wyrafinowana, że ​​użyłem jej, jest stworzenie systemu typu ORP (Object Relational Management). Gdzie można następnie załadować strukturę tabeli bazy danych i zmanipulować dane (z tabeli bazy danych) tak, jakby był to tylko obiekt.

tj

include('blibrary/bLinq.class.inc'); 

$linq = new bLinq(new bLinqSql('mysql://dsn')); 
$r = $linq->from('Users') 
      ->password 
      ->select(); 

co przekłada się na następującym SQL:

SELECT `password` from Users; 

password w select pochodzi z przeciążonej metody.

Wynik może być używany jak:

(array)$r->password; // which outputs an array multiple results of password; 
(string)$r->password; // which outputs a string of the first password hash; 
$r->password[2];  // which outputs a string of the third password hash; 

Chodzi o to, że słowo „password” może być podstawiony przy programowaniu dla każdej innej dziedzinie w bazie danych w locie.

0

Używam __get i __set do łączenia obiektów razem, np.

$user = new User(); 
echo $user->Profile->views; 

To (zwykle) wywołuje niektóre połączenia SQL users.id = profile.user_id.

0

Właściwości (takie jak w języku Python lub C#).Na przykład, gdy używasz coś takiego in Nette można utworzyć jakąś klasę, która wykazuje pewne właściwości jako publiczny:

<?php 
class Foo extends Object 
{ 
    public $bar; 
} 

może masz dostęp do tej nieruchomości naturalny sposób - $instance->bar. Ale jeśli chcesz zrobić walidacji itd., Po prostu dodać getter i setter:

<?php 
class Foo extends Object 
{ 
    private $bar; 

    public function getBar() 
    { 
     return $this->bar; 
    } 

    public function setBar($bar) 
    { 
     if ($bar === NULL) throw new Exception('…'); 
     $this->bar = $bar; 
    } 
} 

I nadal używać $instance->bar. Ale kiedy robisz $instance->bar = NULL;, to tak, jakby dzwonić pod numer $instance->setBar(NULL);.