Używanie OOP w motywach


36

Widzę wiele wtyczek korzystających z kodowania obiektowego, gdy tak naprawdę nie jest to konieczne.

Co gorsza, twórcy motywów zaczynają robić to samo. Motywy komercyjne i bezpłatne popularne motywy, takie jak Suffusion, nawet mój ulubiony motyw - hybrydowy, umieszczają wszystkie funkcje w klasie, tworzą je raz w functions.php i uruchamiają funkcje w sposób proceduralny :)

Wtf? Po co to robić? Oczywiście nie będziesz używać dwóch lub więcej wystąpień tego samego motywu w tym samym czasie.

Załóżmy, że wtyczki robią to dla przestrzeni nazw (co jest śmieszne), ale jaka jest wymówka motywu? Czy coś brakuje?

Jaka jest zaleta kodowania takiego motywu?


5
@Ambitious Amoeba - Czy możesz wyjaśnić, dlaczego uważasz, że używanie klas dla wtyczek w celu minimalizacji kolizji przestrzeni nazw jest śmieszne? Jeśli chodzi o motywy, być może przydałoby się również podać przykłady tego, co uważasz za dobry kod w motywach i co uważasz za niepotrzebne. Omawianie tego w sposób abstrakcyjny raczej nie pozwoli na uzyskanie wglądu w Ciebie ani innych, zwłaszcza tych, którzy nie są zaznajomieni z tym, o czym mówisz.
MikeSchinkel,

1
Korzystam z zajęć tam, gdzie mogę osobiście, dużo łatwiej jest mi je utrzymywać, aktualizować i ponownie wykorzystywać. Niezależnie od osobistych preferencji, jakie są uzasadnione powody korzystania z zajęć?
t31os

1
Dziwne, właśnie zgubiłem swój oryginalny komentarz (być może błąd SE?). Powtórzę to, jakie są dobre powody, aby nie korzystać z zajęć?
t31os

2
@MikeSchinkel: możesz to zrobić, dodając prefiks do nazwy funkcji. Nie sądzę, że warto mieć dodatkowe koszty klasowe, aby mieć ładne nazwy funkcji. W każdym razie jestem ciekawy, dlaczego motywy to robią, nie tyle wtyczek
onetrickpony

4
@Ambitious Amoeba - z pewnością dam ci prawo do swojej opinii, ale moja opinia jest inna. Uważam, że przejrzystość, jaką klasy nadają kodowi poprzez minimalizowanie funkcji pływających w globalnej przestrzeni nazw, jest warta, moim zdaniem, niezmiernie dużej ilości dodatkowego obciążenia, szczególnie przy użyciu profesjonalnego IDE, takiego jak PhpStorm. Klasy tworzą samodzielną jednostkę, dzięki czemu programista może wiedzieć, jakiego kodu wymaga moduł. I wreszcie, po rozwinięciu stylu wtyczki WordPress do używania klas, każda inna metoda wydaje mi się po prostu niechlujnym kodowaniem.
MikeSchinkel,

Odpowiedzi:


26

Rozumiem twoje zamieszanie na podstawie podanego przez ciebie przykładu. To naprawdę kiepski sposób na użycie klasy ... i tylko dlatego, że klasa jest używana, nie powoduje OOP systemu.

W przypadku Hybrid po prostu używają klasy do przestrzeni nazw swoich funkcji. Biorąc pod uwagę, hybrydowy to motyw ramy odbywa się to tak, że dziecko motywy można ponownie używać nazw funkcji bez deweloper konieczności martwienia się o nazwy kolizji. W wielu przypadkach struktura motywu (motyw nadrzędny) jest tak złożona, że ​​wielu programistów motywów podrzędnych nigdy nie zrozumie dokładnie, co dzieje się pod maską.

Gdyby Hybrid nie używał struktury klas, twórcy motywów potomnych musieliby wiedzieć, jakie były wszystkie istniejące wywołania funkcji, aby mogli uniknąć ponownego używania nazw. I tak, możesz po prostu poprzedzić wszystkie swoje funkcje unikalnym ślimakiem, ale to sprawia, że ​​kod jest trudny do odczytania, trudny w utrzymaniu i z natury nie nadaje się do ponownego użycia, jeśli opracujesz kolejne systemy, które chcą korzystać z tej samej funkcjonalności.

Aby odpowiedzieć na twoje pytania

Wtf? Po co to robić? Oczywiście nie będziesz używać dwóch lub więcej wystąpień tego samego motywu w tym samym czasie.

Nie, nie będziesz używać dwóch lub więcej instancji tego samego motywu. Ale tak jak powiedziałem, pomyśl o strukturze klasy w tym przypadku jako o przestrzeni nazw funkcji, a nie o tworzeniu tradycyjnej instancji obiektu. Łączenie wszystkiego w jedną klasę i tworzenie instancji w celu wywoływania metod ( myClass->method();) lub wywoływania metod bezpośrednio ( myClass::method();) to bardzo czysty sposób na uporządkowanie przestrzeni nazw w sposób czytelny i wielokrotnego użytku.

Oczywiście zawsze możesz użyć czegoś takiego myClass_method();, ale jeśli chcesz ponownie użyć dowolnego z tych kodów w innym motywie, wtyczce lub innej ramce, musisz wrócić i zmienić wszystkie swoje prefiksy. Utrzymywanie wszystkiego w klasie jest czystsze i pozwala znacznie szybciej przebudowywać i ponownie wdrażać.

Załóżmy, że wtyczki robią to dla przestrzeni nazw (co jest śmieszne), ale jaka jest wymówka motywu? Czy coś brakuje?

W większości sytuacji zgodziłbym się z tobą. Jednak większość ta szybko zanika. Prowadzę kilka witryn w instalacji MultiSite, które używają odmian tego samego motywu. Zamiast ponownie tworzyć ten sam motyw w kółko z niewielkimi różnicami, mam jedną „klasę” dla motywu nadrzędnego i wszystkie motywy podrzędne rozszerzają tę klasę. To pozwala mi zdefiniować niestandardowe funkcje dla każdej witryny, jednocześnie zachowując ogólne poczucie jednolitości w całej sieci.

Z jednej strony twórcy motywów mogą wybrać oparte na klasach podejście do przestrzeni nazw swoich funkcji (co nie jest śmieszne, jeśli pracujesz w środowisku, w którym wielokrotnie używasz fragmentów tego samego kodu). Z drugiej strony twórcy motywów mogą wybrać podejście oparte na klasach w celu łatwego rozszerzenia o motywy potomne.

Jaka jest zaleta kodowania takiego motywu?

Jeśli korzystasz tylko z Hybrid w swojej witrynie, niewiele wiesz o korzyściach dla Ciebie jako użytkownika końcowego. Jeśli tworzysz motyw podrzędny dla Hybrid, istnieją zalety związane z przestrzenią nazw i rozszerzalnością. Jeśli pracujesz dla ThemeHybrid , zaletą jest szybkie, wydajne ponowne wykorzystanie kodu w innych projektach (Prototyp, Lewiatan itp.).

A jeśli jesteś programistą motywów, który lubi określoną funkcję Hybrid, ale nie cały motyw, zaletą jest szybkie, wydajne ponowne użycie kodu w projekcie niehybrydowym (zakładając, że jest to również GPL).


Nie zgadzam się z częścią dotyczącą „rozszerzalności”. Masz taki sam poziom kontroli nad motywem nadrzędnym, jak gdybyś używał akcji i typowych funkcji. Czemu? Sam to powiedziałeś, to nie jest prawda OOP. Nie zgadzam się również z przestrzenią nazw - dlatego zacząłem to pytanie na pierwszym miejscu - Spróbuj ponownie zdefiniować dowolną funkcję z Hybrid w dowolnej wtyczce, a zobaczysz, że funkcje się zderzą. Jak myślisz, dlaczego nadal dodali prefiksy? :) Po prostu nie możesz owinąć całego motywu w klasie, to po prostu nie ma sensu ...
onetrickpony

Nie twierdzę, że nie używam OOP w motywach, jak niektórzy tutaj mogliby zrozumieć, wręcz przeciwnie (patrz widżety 2.8 dla np. Spacerowiczów itp.), Ale nie tak.
onetrickpony

1
Wygląda na to, że masz problem ze specyficzną implementacją Hybrid, a nie z praktyką używania OOP w kompozycjach, a nawet używania klasy do przestrzeni nazw funkcji zdefiniowanych w kompozycji. Próbowałem odpowiedzieć na twoje szersze pytania dotyczące: dlaczego to zrobić? i re: jakie są zalety robienia tego? Nie zamierzam spędzać czasu na obronie czegoś, co wydaje się być beznadziejnym wdrożeniem, ani na argumentach przeciwko twojej oczywistej niechęci do struktury konkretnego szkieletu tematycznego. Podsumowując, jeśli nie podoba ci się sposób budowania Hybrida, użyj czegoś innego.
EAMann

1
wcale nie lubię Hybrydy (ale oczywiście nie klasy). Hybrid zainspirował mnie do stworzenia własnych ram tematycznych. Weźmy inny przykład: Suffusion, ten sam rodzaj praktyki. Ponownie, przestrzenie nazw w tym przypadku nie działają z motywami, wszystkie funkcje w klasie opakowania zawsze będą powodować konflikty z wtyczkami, ponieważ wtyczki są ładowane przez WP wewnątrz motywów.
onetrickpony

1
Słusznie. Po prostu pamiętaj, że większość prac WP nie jest na początku OOP (ponieważ WP nie jest), ale umieszczenie metod klasy w klasie, aby naśladować sposób, w jaki odbywa się to we wtyczce, jest co najmniej krokiem w prawo kierunek ... nawet jeśli jest to w połowie wymyślona i źle zaimplementowana klasa. Zdecydowanie zgadzam się, że po prostu pakowanie wszystkiego w klasę i wywoływanie procedur proceduralnie jest nieco dziwne (i nie jest przydatne z POV zewnętrznego programisty próbującego korzystać z systemu). Ale jeśli zostanie to zrobione poprawnie (a w Hybrid najwyraźniej nie jest), użycie kodu w kodzie functions.phpmoże być bardzo potężne.
EAMann

29

Prędkość

Mój obecny motyw podstawowy ma 13 klas. Kiedy buduję nowy motyw, albo używam tych klas, jakimi są, lub rozszerzam je. Ten system sprawia, że ​​proces tworzenia nowego motywu jest bardzo, bardzo szybki.

Ciasne lunety

Rzadko potrzebuję zmiennych globalnych, ponieważ wszystko, co mój kod musi wiedzieć, jest ukryte w członkach klasy. Mogę więc dzielić zmienną między dwoma bardzo różnymi filtrami lub akcjami bez ryzyka kolizji ze źle napisanymi wtyczkami.

Konserwacja

Każda klasa to jeden plik. Jeśli muszę zaktualizować motyw klienta, po prostu aktualizuję niektóre pliki. Wszystko, co dzieje się w klasach, zależy ode mnie, dopóki oferuję ten sam interfejs API.

Przykład: powyżej comment_form();połączenia używam prostej akcji:

do_action( 'load_comment_class' );
comment_form();

O tym, która klasa komentarzy zostanie załadowana, decyduje mój kontroler. To, co dokładnie dzieje się w klasie komentarza, decyduje o klasie indywidualnej.

Wypróbuj to z czysto proceduralnym podejściem i zwariujesz. :)

Czytelność

O wiele łatwiej jest ponownie przeczytać i zrozumieć swój kod kilka miesięcy później, jeśli wszystko rozdzieliłeś według jego zadania.

Kilka przykładów przydatnych hierarchii klas

  • Meta_Box-> przedłużony o Shortdesc_Meta_Boxi Simple_Checkbox_Meta_Box-> przedłużony oSidebar_Switch
  • User_Profile_Addon-> przedłużony o User_Profile_Checkbox(patrz pytanie 3255 )
  • Comment_Form -> przedłużony o {$theme_name}_Comment_Form

1
Czy jest jakaś szansa, aby uzyskać zajęcia „tematyczne”? Chcę napisać własne i chciałbym wiedzieć, jak to robisz.
Horttcore,

1
Jeszcze tego nie zdecydowałem. Może w przyszłym roku opracuję nowy motyw podstawowy wraz z @bueltge, który korzysta z niektórych z tych klas. Obawiam się, że najprawdopodobniej nie przed marcem.
fuxia

5
Specjalnie dla twoich skrzynek, darmowych motywów i ram, OOP to droga. Inne osoby muszą pracować z tymi kodami. Autorzy powinni uczynić ten proces tak łatwym i elastycznym, jak to możliwe. Zastąpienie klasy jest łatwiejsze niż zastąpienie 20 funkcji, ponieważ dobrze napisana klasa ma jasno zdefiniowany interfejs API.
fuxia

2
Nie mogę nic powiedzieć o Hybrid; nigdy tego nie użyłem. Ale tak, kontroler, który organizuje wszystko za kurtyną, oferuje dobre filtry i wstawia jakiś wzorzec MVC do zwykłej rozrywki bałagan - to dobra rzecz. Nie ufaj mi Spróbuj. :)
fuxia

3
Nadszedł czas, WordPress potrzebuje motywu OOP dla programistów; mam nadzieję, że poświęcimy czas na pracę nad naszym celem. Ten mały fragment i korzyści pokazują wielkie możliwości związane z tematami klientów; szybki sposób na wdrożenie nowych tematów i świetny również do konserwacji.
bueltge

3

Kolejny punkt do rozważenia: prędkość.

if ( !class_exists('cccYourClassName') )  
// VERSUS  
if ( !function_exists('ccc_your_function_name') )

Po krótkim obejrzeniu / wydrukowaniu znalazłem ~ 1.700 funkcji wewnętrznych i ~ 1.400 funkcji użytkownika = ~ 3.100 / 3.200 funkcji VS. ~ 250 klas. Myślę, że to mówi najwięcej o tym, ile potrzebowałoby spojrzenie. Jeśli potrzebujesz !function_exists('')około 50-100 funkcji w swoim motywie ... po prostu ustaw licznik dla jednej, a następnie zacznij robić matematykę. Nawet jeśli nie jest to OOP, jest to dobry sposób na tworzenie kodu

1) do ponownego użycia
2) do konserwacji
3) do wymiany
4) trochę szybciej

Kiedy spojrzysz na różne klasy unoszące się w Internecie, które pomagają ci szybko tworzyć meta-boxy, widżety itp., Dobrze jest użyć kontrolera takiego jak wspomniany @toscho, ponieważ możesz po prostu podłączyć i wydzielić klasy i po prostu zamienić niektóre linie w kontrolerze, które obsługują twoje klasy.


2

Niektórzy twierdzą, że enkapsulacja jest jedyną (lub przynajmniej podstawową) korzyścią, jaką oferuje OOP, a dziedziczenie i stan są gdzieś pomiędzy nudą a złem:

http://obiecte.blogspot.com/2008/09/oop-sucks.html

Autor mówi bardziej o używaniu klas / obiektów jako struktur niż jako pojemników dla funkcji statycznych, ale interesujące jest przeczytanie zupełnie innego spojrzenia na to pytanie, od kogoś, kto jest poza obozem OOP.

Mogę napisać następną wtyczkę WordPress w Haskell.


1
Niestety blog jest otwarty tylko dla „zaproszonych” użytkowników. Jeszcze jedno przypomnienie, dlaczego nigdy nie powinniśmy publikować naszych informacji w bezpłatnej usłudze, a zamiast tego powinniśmy prowadzić własne blogi. Facebook jest pod tym względem bardzo podobny. Przydałby się zaktualizowany link do zasobu. FWIW Widziałem ciemną stronę OOP i nigdy więcej jej nie użyję, chyba że jest to absolutnie konieczne w kontekście, ponieważ funkcje wyższego rzędu mogą zwykle rozszerzyć funkcjonalność i pomóc zmniejszyć liczbę classsłów kluczowych i niewłaściwe użycie słowa kluczowego.
Josh Habdas

2

Och, całkiem dyskusja! Muszę też przyznać, że o wiele częściej używam klas do enkapsulacji. Pomysł polega na tym, że w moich wtyczkach mogę zawijać funkcje w klasie, aw tej klasie używam bardzo prostych, znaczących nazw metod, które są ogólne nawet wśród innych wtyczek, które piszę. W takim przypadku klasy zastępują przestrzenie nazw, których jestem zmuszony unikać w środowiskach 5.2.x.

Chociaż istnieje kilka przypadków, w których OOP jest użyteczny w przypadku modułowości, prosty czynność owijania funkcji tworzy także dodatkową zaletę rozszerzenia między wtyczkami. Na przykład niedawno rozszerzyłem rozwiązanie do fakturowania oparte na klasach, dlatego mogłem rozszerzyć klasę główną, dodać dodatkowy kod do różnych funkcji (w / wywołanie nadrzędne :: wywołania) lub nawet zastąpić funkcje, wszystko bez internalizacji rozszerzonej wtyczki.

Niestety zawijanie klas w większości zastępuje przestrzenie nazw.


-4

Po co narzekać na kod, którego nie napisałeś?

Jeśli kod Ci się nie podoba, napisz własny!

Prosty. Problem rozwiązany.

Programiści lubią robić rzeczy po swojemu. Nie zakładaj więc, że możesz powiedzieć im, jak napisać kod, jaka whisky do picia, jaki papieros do palenia lub jaką religię wyznawać. Po prostu debugują taką diatrybę i dalej robią, co chcą. ;-)

Kod nie jest poezją. Code jest odmianą piosenki Sinatra „My Way” ...


10
To pytanie nie narzeka na kod, ale wymaga jasnego wyjaśnienia, dlaczego kod zostałby napisany w określony sposób. Duża część rdzenia WP ma charakter proceduralny, a kilka nowszych funkcji wykorzystuje podejście OOP. Wiele nowoczesnych wtyczek używa również OOP do enkapsulacji funkcjonalności. Ale większość motywów nie. OP zapytał, dlaczego zastosować podejście pseudo-OOP, i podał Hybrid jako przykład. Nie odpowiadasz na pytanie, ty się rozpraszasz.
EAMann
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.