2010-12-16 16 views
7

W teoretycznej klasie dostępu do baz danych odkryłem, że istnieje sporo funkcji pomocniczych, których używam w klasie, które nie mają nic do czynienia z instancją klasy (i innymi, które można zmanipulować niezwiązane z instancją klasy za pomocą wtrysku zależności).Wady metod statycznych w PHP

Na przykład mam funkcję, która pobiera ciąg między dwoma innymi ciągami w zmiennej. Myślałem o przeniesieniu tego do klasy String_Helper lub czegoś w tym rodzaju. Ta funkcja została już wykonana statycznie.

Mam również funkcję, która wysyła zapytanie do bazy danych: query($sql). Szczegóły połączenia są dostarczane przez instancję, ale rozważam nadanie jej charakteru statycznego i użycie query($sql, $connection). Programiści mogliby wówczas wywoływać go statycznie i nie musieliby w ogóle tworzyć instancji klasy bazy danych.

Dla mnie pytania to:

  1. Czy warto zrobić coś takiego? Funkcje takie jak funkcja zapytania sprawiają, że zastanawiam się, czy to nie tylko ja staram się, aby wszystko było jak najbardziej statyczne, bez żadnej realnej potrzeby. W jakich okolicznościach uznałbyś to za przydatne?

  2. Wiem, że funkcje statyczne są trudniejsze do przetestowania, ale jeśli upewnię się, że ich kod jest całkowicie niezależny od zależności (lub używa wtrysku zależności w razie potrzeby), to są one równie łatwe do przetestowania, jak wszystko inne, z pewnością?

  3. W tej chwili nie jest to problemem, ale jeśli w przyszłości zdecyduję się rozszerzyć klasy o funkcje statyczne, niemożliwe będzie sprawienie, by obecny kod korzystał z moich rozszerzonych funkcji. Myślałem o Singletonach, ale pojawia się ten sam problem: kod będzie wywoływał Singleton_Class::getInstance(), a nie My_Extended_Singleton_Class::getInstance(). Dependency Injection wydaje się być jedynym sposobem na rozwiązanie tego problemu, ale może to prowadzić do bardziej spójnego API, ponieważ każda zależność musi być podana do obiektu na __construct().

  4. Mam klasę kontenera, która przechowuje pewne informacje statycznie, aby można było uzyskać do nich dostęp w dowolnym miejscu skryptu (zasięg globalny). Gdybym nie mógł używać funkcji statycznych lub pojedynczych, klasa zawierająca instancje różnych zmiennych byłaby świetna. Można użyć na przykład Container::$objects['MyClass'] = $MyClass_object;, a reszta kodu może po prostu uzyskać dostęp do Container::$objects['MyClass']. Jeśli rozszerzyłem klasę MyClass, mógłbym użyć Container::$objects['MyClass'] = $MyExtendedClass_object;, a kod, który użyłby Container::$objects['MyClass'] używałby MyExtendedClass zamiast MyClass. Jest to zdecydowanie najlepszy sposób na zrobienie tego, moim zdaniem, ale chciałbym wiedzieć, co o tym myślisz.

Odpowiedz

9

Ok, niech mi odpowiedzieć na te jeden po drugim ...

1. Czy warto robić coś jak ten

tak i nie. Dzielenie funkcji pomocnika na ich własne klasy to dobry pomysł. Utrzymuje "sztywność" każdej z klas sztywno zdefiniowanych, a ty nie dostajesz zagłębienia. Jednak nie należy wprowadzać metody statycznej tylko dlatego, że można. Metoda zapytania ma ułatwić Ci życie, zarządzając połączeniem, dlaczego więc chcesz stracić tę korzyść?

2. Są one trudniejsze do testowania

nie są one trudniejsze do przetestowania.Metody statyczne zależne od stanu są trudniejsze do przetestowania (dostęp do statycznych zmiennych składowych lub zmiennych globalnych). Jednak ogólnie metody statyczne są równie łatwe do przetestowania jak metody instancji (w rzeczywistości mogą być łatwiejsze, ponieważ nie trzeba się martwić o tworzenie instancji).

3. Rozszerzanie klas

Jest to ważna sprawa. Jeśli umieścisz String_Helper::foo() w klasie, napotkasz problemy. Ale opcja to ustawienie nazwy pomocnika łańcucha jako zmiennej klasy. Więc możesz wtedy zrobić {$this->stringHelper}::foo() (zauważ, tylko PHP 5.3). W ten sposób, aby zastąpić klasę, wszystko, co musisz zrobić, to zmienić klasę pomocniczą string w tej instancji. Ramy Lithium robi to dużo ...

4. Globalny Rejestr

Chciałbym zatrzymać się z dala od tego. Zasadniczo po prostu sprawiasz, że każda klasa jest singletonem bez wymuszania jej. Testowanie będzie koszmarem, ponieważ jesteś teraz zależny od globalnego zasięgu. Zamiast tego utworzyłbym obiekt rejestru i przekazał go do klas za pośrednictwem konstruktora (Dependency Injection). Wciąż osiągasz to samo, ponieważ masz sklep dla obiektów/klas, ale nie jesteś już zależny od zasięgu globalnego. To znacznie ułatwia testowanie.

W ogólnym

Kiedy patrzysz na robienie rzeczy tak, podoba mi się zatrzymać, gdy uderzę takich pytań. Zatrzymaj się, usiądź i zastanów się * Jaki rzeczywisty problem próbuję rozwiązać? "Wyraźnie opisz problem, a następnie wyciągnij nasze rzekome rozwiązania i sprawdź, czy faktycznie je rozwiązują. Jeśli tak, pomyśl o przyszłości i czy te rozwiązania Naprawdę można je utrzymywać na dłuższą metę (zarówno z punktu widzenia naprawy błędów, jak i pod względem dodawania nowych funkcji), tylko jeśli jesteś zadowolony z obu tych odpowiedzi, nawet jeśli zastanawiasz się nad tym, aby to zrobić. . Programowanie nie jest o co najbardziej skomplikowanych, najbardziej mądry lub najbardziej niesamowite rozwiązanie. Chodzi o to, co najprostsze rozwiązanie, które rozwiązuje ten problem ...

mam nadzieję, że pomaga ...

Powodzenia!
+0

Z tymi pytaniami próbowałem rozwiązać dwa problemy: Po pierwsze, czy warto byłoby robić rzeczy statyczne i jakie problemy/wady mogą wynikać z tego. Po drugie, chciałem znaleźć najprostszy sposób na przechowywanie paczki instancji obiektów, udostępniając je w razie potrzeby. Twój pomysł użycia rejestru, który zostanie wstrzyknięty do dowolnej funkcji, która może wymagać zależności, jest genialny, ponieważ oznacza to, że interfejs API nie jest zaśmiecony argumentami dla wszystkich zależności i wciąż mam sposób na zarządzanie dowolną liczbą instancji obiekt. Dziękuję Ci. :) –

+0

@Bruno: Nie ma problemu. Jest to dość standardowy sposób interakcji z dużą liczbą obiektów. Ma tę zaletę, że jest bardzo testowalny, ponieważ po prostu tworzysz rejestr pełen fałszywych obiektów (lub tylko ten, którego klasa potrzebuje twoje testy) i wstrzykujesz to. Nie ma żadnych globalnych skutków ubocznych, więc nie musisz się martwić o przypadkowe złamanie czegokolwiek. Powodzenia ... – ircmaxell

Powiązane problemy