Chcę napisać moduł (framework specific), który obejmowałby i rozszerzał Facebook PHP-sdk (https://github.com/facebook/php-sdk/). Moim problemem jest - jak zorganizować zajęcia w miły sposób.substytucja wielopoziomowego dziedziczenia
Tak się w szczegóły - Facebook PHP SDK składa się z dwóch klas:
- BaseFacebook - klasa abstrakcyjna ze wszystkimi SDK rzeczy robi
- Facebook - rozciąga BaseFacebook i wdraża nadrzędne abstrakcyjnych metod związanych oporność- z domyślnej Zastosowanie sesji
teraz mam jakąś funkcjonalność do dodania:
- Facebook klasa substytucja, zintegrowane z klasą sesji ramy
- metody stenograficzne, który wywołuje run API, używam głównie (poprzez BaseFacebook :: API()),
- metody autoryzacji, więc nie mam do przerobienia tego logika za każdym razem,
- konfiguracja, zasysane z klas ramowych insted przekazywane jako params
- buforowanie, zintegrowany z modułem ramy cache
wiem coś poszło bardzo źle, bo mam zbyt wiele dziedziczenie to nie wygląda zbyt normalnie. Zawijanie wszystkiego w jednej klasie "złożonego rozszerzenia" również wydaje się zbyt duże. Myślę, że powinienem mieć niewiele pracujących klas, ale mam problemy, takie jak: jeśli klasa pamięci podręcznej tak naprawdę nie rozszerza i nie zastępuje metody BaseFacebook :: api() - skrócone i autentykacyjne klasy nie będą mogły korzystać z buforowania.
Może jakiś wzór będzie tutaj? Jak zorganizowałbyś te klasy i ich zależności?
EDIT 04.07.2012
fragmenty kodu, związane z tematem:
ten sposób klasa bazowa Facebooku PHP-SDK:
abstract class BaseFacebook {
// ... some methods
public function api(/* polymorphic */)
{
// ... method, that makes api calls
}
public function getUser()
{
// ... tries to get user id from session
}
// ... other methods
abstract protected function setPersistentData($key, $value);
abstract protected function getPersistentData($key, $default = false);
// ... few more abstract methods
}
Normaly Facebook klasa rozszerza to i impelements tych abstrakcyjnych metod. Wymieniłem go z moim substitude - klasa Facebook_Session:
class Facebook_Session extends BaseFacebook {
protected function setPersistentData($key, $value)
{
// ... method body
}
protected function getPersistentData($key, $default = false)
{
// ... method body
}
// ... implementation of other abstract functions from BaseFacebook
}
Ok, to ja tym bardziej z przedłużenia skrót metod i zmiennych konfiguracyjnych:
class Facebook_Custom extends Facebook_Session {
public function __construct()
{
// ... call parent's constructor with parameters from framework config
}
public function api_batch()
{
// ... a wrapper for parent's api() method
return $this->api('/?batch=' . json_encode($calls), 'POST');
}
public function redirect_to_auth_dialog()
{
// method body
}
// ... more methods like this, for common queries/authorization
}
Nie jestem pewien, czy to nie jest zbyt dużo dla pojedynczej klasy (autoryzacja/skrót metod/konfiguracji). Następnie pojawia się kolejna warstwa rozszerzająca - pamięć podręczna:
class Facebook_Cache extends Facebook_Custom {
public function api()
{
$cache_file_identifier = $this->getUser();
if(/* cache_file_identifier is not null
and found a valid file with cached query result */)
{
// return the result
}
else
{
try {
// call Facebook_Custom::api, cache and return the result
} catch(FacebookApiException $e) {
// if Access Token is expired force refreshing it
parent::redirect_to_auth_dialog();
}
}
}
// .. some other stuff related to caching
}
Teraz to prawie działa. Nowa instancja Facebook_Cache daje mi całą funkcjonalność. Skrócone metody z Facebook_Custom korzystają z buforowania, ponieważ Facebook_Cache nadpisał metodę api().Ale oto, co mnie dręczy:
- Myślę, że to zbyt wiele dziedziczenia.
- To wszystko jest bardzo ściśle powiązane - jak wyglądało określenie "Facebook_Custom :: api" zamiast "parent: api", aby uniknąć pętli metody api() na rozszerzającej się klasie Facebook_Cache.
- Ogólny bałagan i brzydota.
To znowu działa, ale ja po prostu pytam o wzory/sposoby robienia tego w bardziej przejrzysty i inteligentny sposób.
Proszę podać kilka szczegółów, aby uzyskać więcej blisko rozwiązania .. –
Dodałem bitów kodu, sory, że trwało to tak długo. – Luigi
Przy okazji; dziedziczenie wielokrotne to jedna klasa obejmująca więcej niż jedną inną klasę. To coś zupełnie innego. – Sherlock