Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> [OOP] Klasa tylko z funkcjami statycznymi
MiChaSSs
post 28.11.2010, 22:45:07
Post #1





Grupa: Zarejestrowani
Postów: 65
Pomógł: 4
Dołączył: 6.09.2007

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


Hej,
Ostatnio zacząłem przepisywać skrypt na OOP i mam kilka funkcji (nie powiązanych ze sobą), które nie nadają się do standardowej klasy (gdzie tworzy się instancje obiektu) i tak sobie myslałem, czy byłoby prawidłowo jeślibym utworzył klasę (np. Tools czy Utilities) w której trzymałbym przydatne statyczne metody? Czyli stworzyłbym klasę, która nigdy nie będzie miała obiektu a będzie istniała tylko po to, żeby być kontenerem na statyczne metody. Coś na tej zasadzie:

  1. class Tools
  2. {
  3. public static function Metoda1()
  4. {
  5.  
  6. }
  7.  
  8. public static function Metoda2()
  9. {
  10.  
  11. }
  12. }
  13.  
  14. // Wywołanie metod
  15. Tools::Metoda1();
  16. Tools::Metoda2();


I teraz mam pytanie do Was ... ma to jakiś sens? biggrin.gif Jakie jest prawidłowe podejście? Czy funkcje powinny "luzem" w kodzie leżeć a ja nie powinienem za wszelką cenę opakowywać wszystkiego w OOP? Pozdrawiam MD

Ten post edytował MiChaSSs 28.11.2010, 22:45:51
Go to the top of the page
+Quote Post
skowron-line
post 28.11.2010, 22:49:07
Post #2





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

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


Helpery to klasy ze statycznymi metodami możesz zrobić taką klasę tylko z jedną metodą.


--------------------
I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy.

QueryBuilder, Mootools.net, bbcradio1::MistaJam
http://www.phpbench.com/
Go to the top of the page
+Quote Post
Crozin
post 28.11.2010, 23:02:49
Post #3





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

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


Takie konstrukcje są pozbawione sensu z punktu widzenia OOP. Lepiej utwórz sobie odpowiednią przestrzeń nazw, a w niej zwykłe funkcje.
Go to the top of the page
+Quote Post
MiChaSSs
post 29.11.2010, 18:44:08
Post #4





Grupa: Zarejestrowani
Postów: 65
Pomógł: 4
Dołączył: 6.09.2007

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


A istnieje jakis standard, który by definiował co w takim przypadku zrobić?
Go to the top of the page
+Quote Post
mike
post 30.11.2010, 09:44:40
Post #5





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

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


Cytat(skowron-line @ 28.11.2010, 22:49:07 ) *
Helpery to klasy ze statycznymi metodami możesz zrobić taką klasę tylko z jedną metodą.
A niby dlaczego tylko z jedną metodą? Poza "helperami" masz też klasy narzędziowe. Jedna metoda na klasę to bezmyślność.
Cytat(Crozin @ 28.11.2010, 23:02:49 ) *
Takie konstrukcje są pozbawione sensu z punktu widzenia OOP. Lepiej utwórz sobie odpowiednią przestrzeń nazw, a w niej zwykłe funkcje.
Ale jednak nie da się ich uniknąć kiedy piszesz aplikację w duchu OOP.
Klasy narzędziowe to normalna sprawa, czasem są potrzebne i nie należy ich za wszelką cenę unikać.

Cytat(MiChaSSs @ 29.11.2010, 18:44:08 ) *
A istnieje jakis standard, który by definiował co w takim przypadku zrobić?
Klasa narzędziowa to dobre wyjście, jeśli tego faktycznie potrzebujesz. Jedyne co możesz zrobić dodatkowo to zamknąć ją na rozszerzanie i zablokować możliwość tworzenia instancji.
  1. <?php /* już nie pamiętam czy w PHP jest final */ final class Tools {
  2.  
  3. private Tools() {
  4. throw new Exception("IllegelStateException");
  5. }
  6.  
  7. // Jakieś funkcje
  8. }
  9.  
  10. ?>


Ten post edytował mike 30.11.2010, 09:45:38
Go to the top of the page
+Quote Post
skowron-line
post 30.11.2010, 10:02:49
Post #6





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

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


Cytat(mike @ 30.11.2010, 09:44:40 ) *
A niby dlaczego tylko z jedną metodą? Poza "helperami" masz też klasy narzędziowe. Jedna metoda na klasę to bezmyślność.


Tak mi się napisało, poza tym helpery nie muszą być klasami statycznymi w Zend nie są.


--------------------
I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy.

QueryBuilder, Mootools.net, bbcradio1::MistaJam
http://www.phpbench.com/
Go to the top of the page
+Quote Post
marcio
post 30.11.2010, 12:35:10
Post #7





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


Cytat
Tak mi się napisało, poza tym helpery nie muszą być klasami statycznymi w Zend nie są.

W symfony mamy funkcje typu include_partial() ktore w pewnym sensie tez sa helperami...wedlug mnie takie maja dzialanie poprostu zamykasz w funkcji/klasie czesto wykonywane czynnosci lecz niezbyt rozbudowane.

p.s oczywiscie jesli w klasie to jako metody statyczne

Ten post edytował marcio 30.11.2010, 12:35:36


--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
Go to the top of the page
+Quote Post
Zyx
post 30.11.2010, 22:58:02
Post #8





Grupa: Zarejestrowani
Postów: 952
Pomógł: 154
Dołączył: 20.01.2007
Skąd: /dev/oracle

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


Z funkcjami jest taki problem, że nie podlegają automatycznemu ładowaniu. Tutaj funkcjonalność OOP jest tylko narzędziem do uzyskania żądanych efektów, czyli funkcji + automatycznego ładowania.


--------------------
Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0
Go to the top of the page
+Quote Post
aart3k
post 1.12.2010, 12:43:34
Post #9





Grupa: Zarejestrowani
Postów: 72
Pomógł: 10
Dołączył: 2.02.2008
Skąd: Kraków

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


Reasumując: biorąc pod uwagę ograniczenia PHP (właśnie podane przez zyx'a) nie jest złym rozwiązaniem wrzucenie do klasy funkcji statycznych i niejako traktować klasę jak przestrzeń nazw.

Tak btw, jak masz dobrze zaprojektowany kod, to sytuacja w której chcesz utworzyć klasę Tools tylko ze statycznymi funkcjami nie ma prawa zaistnieć.
Go to the top of the page
+Quote Post
Quadina
post 1.12.2010, 13:56:09
Post #10





Grupa: Zarejestrowani
Postów: 200
Pomógł: 38
Dołączył: 1.12.2010
Skąd: Wrocław

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


Zgodzę się z użytkownikiem aart3k na prawie całej linii. Dobrze zaprojektowany model nie potrzebuje przestrzeni narzędzi. Jednak tak się czasem zdarza, że chcemy sobie różne rzeczy uprościć z punktu widzenia programistycznego obciążająć serwer. Dobrym przykładem jest tutaj helper Form z framework Symfony. Masz tam kupę funkcji generujących tylko i wyłącznie kod HTML, który bądź co bądź powinieneś generować samemu. A jednak w pewnych warunkach (np. dopuszczenie do szablonów php grafka) wymaga się takich a nie innych operacji. Wszystko zależy nie tylko od efektu jaki chcesz uzyskać, ale również od warunków. Ogólnie powtórze jak echo po aart3k: Dobrze zaprojektowany model nie potrzebuje takiego typu klas narzędziowych jak opisujesz.


--------------------
Warsztat: NetBeans 7.2 Beta, PHP, MySQL, PostgreSQL, Symfony (<=1.4), Diem, Java, Sieci neuronowe
Go to the top of the page
+Quote Post
Crozin
post 1.12.2010, 14:36:57
Post #11





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

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


Hmmm... faktycznie brak autoloadera to już poważna wada (to nie jest ironia tylko przyznanie racji).

Cytat
Tak btw, jak masz dobrze zaprojektowany kod, to sytuacja w której chcesz utworzyć klasę Tools tylko ze statycznymi funkcjami nie ma prawa zaistnieć.
Ma prawo i takie coś jest powszechnie stosowane. Oczywiście można każdorazowo tworzyć nową instancję na zasadzie:
  1. $text = new StringUtils()->doSth($text); // PHP 5.4
  2.  
  3. $stringUtils = new StringUtils();
  4. $text = $stringUtils->doSth($text); // PHP < 5.4
Albo utworzyć sobie jakiś obiekt-kolekcję dla tego typu klas, który zwróci nam jedną automatycznie zainicjalizowany obiekt:
  1. $text = $this->getUtilClass('String')->doSth($text);
Ale skorzystanie z metod statycznych jest po prostu dużo wygodniejsze i czytelniejsze.
Go to the top of the page
+Quote Post
aart3k
post 1.12.2010, 15:27:22
Post #12





Grupa: Zarejestrowani
Postów: 72
Pomógł: 10
Dołączył: 2.02.2008
Skąd: Kraków

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


@Crozin: you missed the point, chodziło o klasę Tools z narzędziami niepowiązanymi ze sobą.
Go to the top of the page
+Quote Post
athabus
post 1.12.2010, 15:51:43
Post #13





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

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


Ja mam cały zbiór klas pomocniczych. Nazwałem go Cat - sam już nie pamiętam od czego to był skrót ;-) W nim mam klasy takie jak np.
Cat_Converter_String
Cat_Converter_Price
Cat_Converter_Array

Umieszczam je w każdym praktycznie projekcie, który robię. Np. po co tysiąc razy pisać metodę do przeliczania ceny brutto, naliczania rabatów, czy "slugowania" stringa jak można to umieścić w klasach pomocniczych. Jest to lepsze rozwiązanie, bo oszczędza czas i ogranicza głupie pomyłki.

Umieszczanie wszystkiego w modelu jest imo kiepskim pomysłem. Przykład nie będzie przeliczanie cen netto na ceny brutto - jeśli umieścisz to w modelu np. sklepu internetowego, gdzie robisz takie przeliczenia w wielu miejscach to po pewnym czasie mogą pojawić się niekonsekwencje typu:
- w jednym miejscu zaokrąglasz cenę a w drugim wartość produktów przez co otrzymujesz inne wyniki
- w przypadku dodania rabatu w jednym miejscu będziesz skracał dopiero wynik końcowy a w innym skrócisz raz po obliczeniu rabatu a następnie po obliczeniu ceny brutto - i znowu powstają groszowe niezgodności, które trudno potem wychwycić.

Mając wszystko scentralizowane łatwiej uniknąć takich głupich błędów. Ja osobiście lubię klasy z statycznymi metodami narzędziowymi i często korzystam. Autoloader też jest dla mnie ważny bo upraszcza kod.
Go to the top of the page
+Quote Post
thek
post 1.12.2010, 16:04:51
Post #14





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Może więc aart3k chodzi Ci o system helperów z Kohany? Bo nie wiem czy dobrze zrozumiałem. Podam przykład jednego z wbudowanych helperów Kohany:
  1. class security_Core {
  2.  
  3. public static function xss_clean($str)
  4. {
  5. return Input::instance()->xss_clean($str);
  6. }
  7.  
  8. public static function strip_image_tags($str)
  9. {
  10. return preg_replace('#<img\s.*?(?:src\s*=\s*["\']?([^"\'<>\s]*)["\']?[^>]*)?>#is', '$1', $str);
  11. }
  12.  
  13. public static function encode_php_tags($str)
  14. {
  15. return str_replace(array('<?', '?>'), array('&lt;?', '?&gt;'), $str);
  16. }
  17.  
  18. }
które wywołuje się statycznie nazwa_helpera::nazwa_metody(parametry)
Oczywiście w Kohanie nie istnieje jeden taki worek, ale takich klas jest wiele, zazwyczaj w sensowniejsze grupy poukładana. Jak zauważono, dobrze napisany skrypt nie potrzebuje ich, ale nieraz zamiast pisać kod od razu "ciurkiem" od razu poprawnie, wygodniej sobie takie klasy zdefiniować, by nie powtarzać co i rusz tego samego kodu, wielokrotnie długiego. Widząc niektóre jednak można się śmiać (patrząc na helper Array zobaczyć można ile to wywołania wariacji array_push/pop/shift czy innych wbudowanych), ale dla nie sięgających głębiej w bebechy frameworka takie pomocne dodatki są wybawieniem. Sam nieraz sobie pisze takie by przykładowo zamiast kilkunastu linijek kodu zgrabnie kod ująć jednym wywołaniem.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
MiChaSSs
post 1.12.2010, 17:36:28
Post #15





Grupa: Zarejestrowani
Postów: 65
Pomógł: 4
Dołączył: 6.09.2007

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


Okej, czyli poprawiając mój pierwszy, aby upewnić się że klasa nie będzie miała instancji, jej definicja powinna wyglądać tak:

  1. abstract class Tools
  2. {
  3. public static function Metoda1()
  4. {
  5.  
  6. }
  7.  
  8. public static function Metoda2()
  9. {
  10.  
  11. }
  12. }
  13.  
  14. // Wywołanie metod
  15. Tools::Metoda1();
  16. Tools::Metoda2();


Mam racje? Dziękuję wszystkim za pomoc, pozdrawiam MD
Go to the top of the page
+Quote Post
aart3k
post 1.12.2010, 18:52:28
Post #16





Grupa: Zarejestrowani
Postów: 72
Pomógł: 10
Dołączył: 2.02.2008
Skąd: Kraków

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


nie wiem czy z abstracta można wywoływać statyczne.

@thek: Kohany nie znam, wiem zaś że rozwiązanie które opisałeś świetnie się sprawdza, niezależnie od stosowanego frameworka.
U siebie mam parę właśnie tego pokroju klas, niektóre mające tylko jedną funkcję, nie mniej jednak chodzi o to żeby były logicznie spójne np. mój MM_Geolocator ma tylko statyczną getCountryByIp.
Go to the top of the page
+Quote Post
mike
post 1.12.2010, 21:18:08
Post #17





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

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


Cytat(MiChaSSs @ 1.12.2010, 17:36:28 ) *
Okej, czyli poprawiając mój pierwszy, aby upewnić się że klasa nie będzie miała instancji, jej definicja powinna wyglądać tak:
Po klasie abstrakcyjnen można odziedziczyć i wtedy utworzenie instancji stoi otworem.
Zrób klasę finalną z prywatnym konstruktorem, z którym rzucisz wyjątek tak jak pokazałem w poprzednim poście.
Cytat(aart3k @ 1.12.2010, 18:52:28 ) *
nie wiem czy z abstracta można wywoływać statyczne.
Można.
Go to the top of the page
+Quote Post
MiChaSSs
post 1.12.2010, 22:37:23
Post #18





Grupa: Zarejestrowani
Postów: 65
Pomógł: 4
Dołączył: 6.09.2007

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


Cytat(aart3k @ 1.12.2010, 18:52:28 ) *
nie wiem czy z abstracta można wywoływać statyczne.


Abstract służy właśnie do tego, żeby nie trzeba było mieć instancji obiektu, aczkolwiek jak słusznie zauważył kolega mike nie oznacza to, że nie można po tym dziedziczyć. Dziękuję za Waszą pomoc, pozdrawiam MD
Go to the top of the page
+Quote Post
manro
post 2.12.2010, 16:55:45
Post #19





Grupa: Zarejestrowani
Postów: 9
Pomógł: 3
Dołączył: 25.10.2006

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


Cytat(MiChaSSs @ 1.12.2010, 23:37:23 ) *
Abstract służy właśnie do tego, żeby nie trzeba było mieć instancji obiektu, aczkolwiek jak słusznie zauważył kolega mike nie oznacza to, że nie można po tym dziedziczyć. Dziękuję za Waszą pomoc, pozdrawiam MD

Abstract służy do tego żeby nie można było bezpośrednio z tej klasy stworzyć instancji obiektu, a nie do tego żeby nie trzeba było mieć instancji obiektu, jak sama nazwa wskazuje określa to abstrakcyjny model, którego instancja fizyczna nie istnieje. Pozwala to natomiast tworzenie konkretnych instancji obiektów danego typu np:

abstract class Animal {}
class Dog extend Animal {}
class Cat extend Animal {}


--------------------
If you don't have time to do it right, where are you going to find the time to do it over?
http://www.nowicki.cjb.net
Go to the top of the page
+Quote Post
athabus
post 2.12.2010, 17:04:01
Post #20





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

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


Dokładnie jak kolega wyżej pisze. Twoje zastosowanie abstract w sumie działa, ale nie jest do końca zgodne z ideą OOP - abstract ma bardziej pełnić rolę interfejsu, tyle że "rozbudowanego" o część metod.

Dzięki temu można np. stworzyć kolekcje obiektów o jednolitym interfejsie i np. po nich potem iterować.

Użycie klasy abstract w sposób jaki tutaj proponujesz jest niewłaściwe - mike podał ci eleganckie rozwiązanie zgodne z ideą OOP.
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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 Wersja Lo-Fi Aktualny czas: 23.04.2024 - 15:06