Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Klasa odwołująca się do sterownika
mstraczkowski
post
Post #1





Grupa: Zarejestrowani
Postów: 273
Pomógł: 52
Dołączył: 3.02.2013
Skąd: Przemyśl

Ostrzeżenie: (0%)
-----


Witam was,

Mam drobne pytanie, bo albo już jestem przemęczony, albo nie wiem.

Co chcę osiągnąć:

Chcę utworzyć obiekt klasy, do której będę się odwoływać, natomiast nie będę odwoływał się tak naprawdę bezpośrednio do niej, tylko do jej adaptera, który jest ustalany na podstawie konfiguracji.

Przykładowo klasa Cache, posiada możliwe 3 adaptery: file, apc lub memcached, wybrany w konfiguracji jest apc, chciałbym teraz móc zrobić tak:

Cytat
Uwaga: Nie chcę robić przykładowo Cache::getInstance(), aby otrzymać obiekt adaptera, chcę działać na obiekcie klasy Cache.


  1. <?php
  2. // Wybrany w konfiguracji apc
  3. $cache = new Cache();
  4. $cache->store(); // Skutkuje wywołaniem metody store w adapterze APC
  5.  
  6. // Zmieniam sobie konfigurację na file
  7. $cache = new Cache();
  8. $cache->store(); // Skutkuje wywołaniem metody store w adapterze File

Każda klasa adaptera rzecz jasna implementuje interfejs, więc zbiór ich metod jest taki sam

Moje rozwiązanie:

Rozwiązałem to zagadnienie używając metody magicznej __call, która uruchomi się wtedy gdy danej metody nie ma w klasie Cache, wtedy ta metoda jest wykonywana z wybranego adaptera.

Moje pytanie

Czy jest jakiś lepszy sposób na osiągnięcie opisanego przeze mnie efektu ?

Pozdrawiam i dzięki za sugestie.

Ten post edytował mstraczkowski 8.03.2013, 14:31:49


--------------------
Jeżeli moja wypowiedź Ci pomogła użyj przycisku
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 12)
nospor
post
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Raczej nie ma innej metody.
Od biedy możesz w klasie Cache stworzyć metode store() a tej metodzie odpalać metodę store() aktualnego adaptera. No ale to wcale nie jest lepsze rozwiązanie smile.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
mstraczkowski
post
Post #3





Grupa: Zarejestrowani
Postów: 273
Pomógł: 52
Dołączył: 3.02.2013
Skąd: Przemyśl

Ostrzeżenie: (0%)
-----


@up Tak, też to brałem to pod uwagę i też uważam, że to nie jest lepsze rozwiązanie - zbędne pisanie kodu moim zdaniem.


--------------------
Jeżeli moja wypowiedź Ci pomogła użyj przycisku
Go to the top of the page
+Quote Post
melkorm
post
Post #4





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

Ostrzeżenie: (0%)
-----


No na pewno będzie to czytelniejsze rozwiązanie niż __call moim zdaniem.


--------------------
Go to the top of the page
+Quote Post
nospor
post
Post #5





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
No na pewno będzie to czytelniejsze rozwiązanie niż __call moim zdaniem.
ALe upierdliwe.... bedziesz miał 10 metod do wykonania to będziesz musial pisać 10 metod w cache. A tak jeden call i już

Można zrobić tablicę z nazwami metod, które można wywoływać w adapter i w ten sposób przez call wywoływać tylko te, które są w tablicy
Powód edycji: [nospor]:


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
melkorm
post
Post #6





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

Ostrzeżenie: (0%)
-----


Hum, jednorazowe napisanie metod, a wygoda czyli podpowiedzi IDE itp, cóż moim zdaniem kwestia podejścia smile.gif


--------------------
Go to the top of the page
+Quote Post
nospor
post
Post #7





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
cóż moim zdaniem kwestia podejścia
Racja smile.gif



--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
mstraczkowski
post
Post #8





Grupa: Zarejestrowani
Postów: 273
Pomógł: 52
Dołączył: 3.02.2013
Skąd: Przemyśl

Ostrzeżenie: (0%)
-----


Tzn wiesz, podczas rozwijania kodu doszła by nowa metoda, wtedy musimy dodać ją do każdego sterownika + interfejs + klasa główna.
m.in dlatego zadałem to pytanie bo IDE mało podpowiada przy takim zastosowaniu, ale tak jak mówisz to już kwestia podejścia.


--------------------
Jeżeli moja wypowiedź Ci pomogła użyj przycisku
Go to the top of the page
+Quote Post
melkorm
post
Post #9





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

Ostrzeżenie: (0%)
-----


Cytat
Tzn wiesz, podczas rozwijania kodu doszła by nowa metoda, wtedy musimy dodać ją do każdego sterownika + interfejs + klasa główna.


Załóżmy że masz 3 sterowniki i interejs to musisz dodać metodę w 4 miejscach mając __call, mając proxy metody w Cache musiałbyś dodać o jedną metodę więcej niż w przypadku __call, dla mnie nigdy nie stwarzało to problemu, chwila roboty za czytelność - ale jak już mówiłem kwestia podejścia.

Ten post edytował melkorm 8.03.2013, 14:51:04


--------------------
Go to the top of the page
+Quote Post
CuteOne
post
Post #10





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

Ostrzeżenie: (0%)
-----


Cytat
Chcę utworzyć obiekt klasy, do której będę się odwoływać, natomiast nie będę odwoływał się tak naprawdę bezpośrednio do niej, tylko do jej adaptera

http://www.oodesign.com/factory-pattern.html
Go to the top of the page
+Quote Post
Crozin
post
Post #11





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. Skoro wszystkie sterowniki (powiedzmy: APCCache, FileCache i ArrayCache) implementują wspólny interfejs i tylko on Cie obchodzi to nic nie stoi na przeszkodzie by rozwiązać to tak:
  1. /** @var $cache My\CacheInterface */
  2. $cache = new APCCache();
2. Jednak domyślam się, że w Twoim przypadku APC, File czy Array to jedynie miejsce składowania danych, a obiekty te zapewne mają jedynie metody get(), set(), has(). Zaś sama klasa Cache może mieć już jakieś bardziej złożone metody, które jedynie korzystają ze "składowiska" cache'u. Dlatego też najprawdopodobniej powinieneś to rozwiązać w ten sposób:
  1. $cache = new Cache(new APCStorage()); // albo: new Cache(new FileStorage('/path/to/dir'));
3. Jeżeli część/wszystkie metody z obiektu APCStorage miałby być również dostępne bezpośrednio przez obiekt Cache powinieneś dla każdej metody utworzyć metodę proxy, a nie stosować żadnego porąbanego __call(). Dlaczego __call() jest porąbane?
3.1. Zamiast n metod proxy masz jedną, w której masz n skomplikowanych IF-ów sprawdzających czy nazwa metody jest w ogóle w porządku oraz czy jej argumenty są poprawne (ilość, typ).
3.2. Tracisz wsparcie ze strony IDE, narzędzi dokumentujących czy ogólnie analizujących kod.
3.3. Kilka rodzajów błędów, które normalnie można wykryć na etapie "kompilacji" (w przypadku PHP trzeba tutaj ująć to w spory cudzysłów) staje się błędami czasu wykonywania - czyli stają się gorszymi błędami.
3.4. PHP nie ma co prawda jakiś specjalnych optymalizatorów o JIT-cie nie wspominając, ale może niedługo coś się z tym tematem ruszy - Twój kod nie skorzysta na tym. Google: PHP HipHop

@CuteOne: Fabryka? Jakie niby miałaby mieć tutaj zastosowanie?

Ten post edytował Crozin 8.03.2013, 17:43:51
Go to the top of the page
+Quote Post
mstraczkowski
post
Post #12





Grupa: Zarejestrowani
Postów: 273
Pomógł: 52
Dołączył: 3.02.2013
Skąd: Przemyśl

Ostrzeżenie: (0%)
-----


Dzięki wielkie za sugestię, zastosuję metody proxy, wsparcie IDE jest dla mnie dosyć ważną rzeczą.


--------------------
Jeżeli moja wypowiedź Ci pomogła użyj przycisku
Go to the top of the page
+Quote Post
viking
post
Post #13





Grupa: Zarejestrowani
Postów: 6 380
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Ja po przeczytaniu też zrozumiałem że chodzi o fabrykę. Czyli wywoływanie
  1. $cache = Cache::factory('Apc', $options);

gdzie te obiekty implementują jakąś abstrakcję albo interface'y stąd późniejsze
  1. $cache->store()

niezależne od adaptera cache.


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 17:06