![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Witam,
na wstępie trochę kodu 1.
2.
i pytanie - czy istnieje, możliwość przechwycenia z zewnątrz, momentu zainicjowania(1) $this->a lub zmiany jego wartości(2)? EDIT: __set() nie wchodzi w grę Ten post edytował CuteOne 9.11.2012, 16:18:09 |
|
|
![]()
Post
#2
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Utwórz setter, który tuż po nadaniu wartości utworzy zdarzenie, które poinformuje o zmianie wartości wszystkich subskrybentów. Google: php observator/event dispatcher.
|
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Właśnie chciałem uniknąć obserwatora ;P ale wydaje mi się, że ten sposób będzie najlepszy. Jeszcze jedno pytanie jeśli, można - co w przypadku zmiennych lokalnych danej metody:
Kombinowałem z closures http://www.php.net/manual/en/functions.anonymous.php#95124 ale wtedy dana zmienna staje się zależna od wartości zewnętrznych Ten post edytował CuteOne 9.11.2012, 16:59:38 |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Dlaczego chciałeś uniknąć obserwatora czy event dispatchera?
Cytat Jeszcze jedno pytanie jeśli, można - co w przypadku zmiennych lokalnych danej metody Najzwyczajniej w świecie odczep się od nich. ![]() Opisz może co jest faktycznym problemem, bo wygląda na to, że mamy tutaj do czynienia z problemem XY. |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Tworzę system pluginów na bazie Zenda. Z tą różnicą, że pluginem, może być nie tylko klasa rozszerzająca "Zend_Plugin_Abstract" ale cały moduł z kontrolerami, modelami i wszystkim tym co zawiera standardowy moduł + własne pluginy(rozszerzające Zend_Plugin_Abstract). Innymi słowy moduły mogą być rozszerzane przez inne moduły(i ich pluginy), które mogą być dalej rozszerzane i tak w nieskończoność...
Uproszczony przykład dwóch niezależnych od siebie modułów - "pseudopluginów"
oraz ich konfiguracja. list - lista zainstalowanych pluginów, action - definicja zależności pomiędzy pluginami
Dla zwiększenia, możliwość ingerowania w dane i funkcjonalność, danej metody zastosowałem pseudo AOP (before, after, around). Before i after mam już rozwiązane, problem to around czyli możliwość ingerencji w metodę podczas jej wykonywania np. w zmienną $row przed lub po jej zainicjowaniu. |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Nawet AOP nie zakłada takiego pogwałcenia kolejności wykonywania kodu jak ingerencja we wnętrze jakiejś metody.
Według mnie powinieneś tutaj skorzystać z event dispatchera i tworzyć bardzo dużo zdarzeń, gdzie część z nich będzie miała możliwość modyfikowania obiektu, którego dane zdarzenie dotyczy. Dzięki temu będziesz mógł bez problemu podpiąć np. BBCode* przez proste podpięcie go pod odpowiednie zdarzenia w systemie. * zlituj się nad swoimi użytkownikami i nie katuj ich tym paskudnym i niewygodnym formatem. |
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Zrobiłem małą inwentaryzację swoich pomysłów "jak pluginować pluginy" i doszedłem do kilku wniosków:
- pisanie nowych pluginów musi być równie proste jak pisanie zwykłych modułów (ameryki nie odkryłem ale to chyba będzie największe wyzwanie przy pisaniu systemu) - każdy kontroler, model czy widok musi posiadać odgórnie wyznaczone miejsca dostępu (hooki) dla danych wrażliwych(widać bez obserwatora się nie obejdzie ![]() - każdy moduł(pseudopligin) musi posiadać własne API, dzięki czemu możliwe będzie sterowanie modułem przy użyciu innego modułu. Nad tą kwestią muszę się jeszcze zastanowić - co, jak i gdzie ![]() - idąc Twoją radą zrezygnuje z możliwości manipulowania zmiennymi danych metod. - rozszerzanie pluginu przez inny plugin (tak jak w akcji Comments->viewAction() => BBCode->view()), będzie możliwe poprzez: 1. Nadpisanie metody 2. Hooki 3. Before i After 4. Za pomocą serializacji obiektu i zmianach struktury przed jego deserializacją (do przemyślenia) 5. Za pomocą API Zostało jeszcze parę(naście) kwestii do przemyślenia ale to już pierdółki. Teraz zastanawiam się w jaki sposób uaktualniać już zainstalowane pluginy - wsteczna kompatybilność i te sprawy. Gdyby istniała, możliwość dziedziczenia metod rodzica przez dziecko bez ingerencji w kod.. Co do BBCode to tylko przykład ![]() Pozdrawiam i dziękuję za Twoje rady Edit: co do Event Dispatchera to nie mam na jego temat wystarczającej wiedzy abym mógł napisać "profesjonalny" system - pracuje na Zend 1.x.x, może za jakiś czas zagłębie się w niego dokładniej gdy będę przechodził na Zenda 2. Ten post edytował CuteOne 10.11.2012, 21:34:04 |
|
|
![]()
Post
#8
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Nie do końca rozumiem co dokładnie chcesz stworzyć (to chyba przez to, że słowa plugin/moduł mają po 1000 znaczeń :]) ale...
Cytat każdy kontroler, model czy widok musi posiadać odgórnie wyznaczone miejsca dostępu (hooki) dla danych wrażliwych(widać bez obserwatora się nie obejdzie ) Odgórne narzucanie czegokolwiek lubi się mścić.Cytat - rozszerzanie pluginu przez inny plugin (tak jak w akcji Comments->viewAction() => BBCode->view()), będzie możliwe poprzez: 1. Nadpisywanie niemal zawsze jest najgorszym sposobem rozszerzania o dodatkowe, potencjalnie niepowiązane funkcje.1. Nadpisanie metody 2. Hooki 3. Before i After 4. Za pomocą serializacji obiektu i zmianach struktury przed jego deserializacją (do przemyślenia) 5. Za pomocą API 4. Nawet się nie waż takich głupot robić. 5. Nie rozumiem co masz na myśli tutaj przez API (znowu, 1000 znaczeń tego słowa). Zadbaj o to by w systemie było dużo zdarzeń, przykładowo: Takie proste rozwiązanie, powinno sprawdzić się w zdecydowanej większości przypadków. Nie tworzy ono też żadnych powiązań pomiędzy "głównym kodem" a pluginami. Cytat Teraz zastanawiam się w jaki sposób uaktualniać już zainstalowane pluginy - wsteczna kompatybilność i te sprawy. Gdyby istniała, możliwość dziedziczenia metod rodzica przez dziecko bez ingerencji w kod.. W zależności od tego, jak solidne/rozbudowane narzędzie chcesz uzyskać, a: oprzyj to o zwykły menadżer zależności (np. PHP-owski Composer), b: nie mam pojęcia czy istnieje jakiś odpowiednik w PHP (pewnie nie), ale pogoogleaj za Java OSGi - bardziej za architekturą i sposobie działania.Cytat Edit: co do Event Dispatchera to nie mam na jego temat wystarczającej wiedzy abym mógł napisać "profesjonalny" system - pracuje na Zend 1.x.x, może za jakiś czas zagłębie się w niego dokładniej gdy będę przechodził na Zenda 2. A po co niby pisać samemu coś co już jest? Ot, chociażby ten dostępny w Symfony: https://github.com/symfony/EventDispatcher
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Cytat Nie do końca rozumiem co dokładnie chcesz stworzyć (to chyba przez to, że słowa plugin/moduł mają po 1000 znaczeń :]) ale... Musze zaprojektować system ERP a właściwie podstawkę, którą można dowolnie rozszerzać. Taki system z reguły składa się z kilkunastu niezależnych od siebie elementów np. HR, work flow, crm. Elementy te są na tyle "duże", że zastosowanie zwykłego systemu pluginów odpada, dlatego pomyślałem aby pluginem mógł być pojedynczy moduł np. Kod modules default |-controllers |-models |-views hr |-controllers |-models |-views |-plugins crm |-controllers |-models |-views Na etapie projektowania tak rozbudowanego systemu nie jestem w stanie przewidzieć zależności pomiędzy poszczególnymi modułami np. Work Flow, może być użyty w CRM'ie, statystyki sprzedaży z CRM'a mogą być użyte w HR do generowania raportów, raporty z HR mogą być wykorzystane przez Work Flow itd. Sprawę dodatkowo komplikuje fakt, że moduły będą pisane przez zupełnie nie znanych mi programistów a więc system musi być przejrzysty, intuicyjny i przede wszystkim na tyle "łatwy" aby pisanie dodatkowych modułów nie była przeprawą rzez piekło. Cytat Odgórne narzucanie czegokolwiek lubi się mścić. Pewnie tak ![]() Cytat 1. Nadpisywanie niemal zawsze jest najgorszym sposobem rozszerzania o dodatkowe, potencjalnie niepowiązane funkcje. 4. Nawet się nie waż takich głupot robić. 5. Nie rozumiem co masz na myśli tutaj przez API (znowu, 1000 znaczeń tego słowa). 1. Teraz gdy zobaczyłem Twój przykład z dispatcherem to faktycznie nadpisywanie nie miało by sensu 4. Gdzieś widziałem przykład wykorzystania serializacji do zmian w strukturze klasy podczas aktualizacji i powiem ci, że byłem wniebowzięty takim podejściem do problemu ;P 5. API:
W ten sposób mamy dostęp do zdefiniowanych w API metod bez bezpośredniego wywoływania modeli, kontrolerów itp. z innych modułów. Cytat W zależności od tego, jak solidne/rozbudowane narzędzie chcesz uzyskać, a: oprzyj to o zwykły menadżer zależności (np. PHP-owski Composer), b: nie mam pojęcia czy istnieje jakiś odpowiednik w PHP (pewnie nie), ale pogoogleaj za Java OSGi - bardziej za architekturą i sposobie działania. Pogooglam dzięki za wskazówkę Ten post edytował CuteOne 12.11.2012, 09:10:39 |
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Pewnie tak ale jakoś muszę udostępnić miejsca, w których klasa A będzie mogła zmienić model w klasie B bez ingerencji w kod (jeden z wymogów projektu..). Standardowe rozwiązanie tego problemu, które od lat się całkiem dobrze sprawdza, to IoC (zrealizowane np. przez DIC-a) + IDD. Jeżeli tylko swój własny kod będziesz pisał tak jakby był on przeznaczony jako tzw. 3rd-party-code, nie powinieneś mieć problemów - chociaż jest to bardziej czasochłonne, a kod czasami komplikuje się na dłuższą metę może przynieść to sporo oszczędności (czasu i pieniędzy).Cytat Gdzieś widziałem przykład wykorzystania serializacji do zmian w strukturze klasy podczas aktualizacji i powiem ci, że byłem wniebowzięty takim podejściem do problemu ;P "Oryginalne" podejście do tematu niemal zawsze oznaczać będzie złe podejście.
|
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Twoje rady jak zawsze trafiają w dziesiątkę! Dziękuje bardzo za pomoc, teraz muszę ponownie zrobić remanent swoich pomysłów - zajmie to pewnie z tydzień, dwa. W razie wątpliwości mam nadzieję, że użyczysz mi swojej fachowej wiedzy.
Jeszcze raz dziękuję i pozdrawiam Edit: Wstępny projekt architektury aplikacji już mam ![]() Legenda: - EventDispatcher pochodzi z Symfony2 - ED skrót od EventDispatchera - Plugin Manager - rejestruje wszystkie akcje pluginów do ED - Resource Manager - standardowy Zendowski loader (lekko zmodyfikowany) - ViewAction - renderowanie widoku Kolejność ładowania klas od lewej do prawej, z góry na dół. Nadal jednak nie rozwiązałem problemu zmiany modeli ;P W teorii bez problemu można wstrzyknąć modelX, Y, Z ale przy rozbudowanych akcjach będzie to wyglądało dość komicznie
Drugim problem jest brak kontroli nad wstrzykiwanymi modelami
Dzisiaj poświęcę parę godzin nad studiowaniem wzorców, może znajdę rozwiązanie tego problemu Ten post edytował CuteOne 15.11.2012, 09:36:07 |
|
|
![]()
Post
#12
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Ale dlaczego chcesz dla danego obiektu wstrzykiwać inne obiekty przy pomocy tablicy, a nie jak sam pokazałeś, jako osobne parametry?
|
|
|
![]()
Post
#13
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
![]() W sumie to sam nie wiem. Ubzdurałem sobie aby wstrzykiwać modele pakietami Kod { "use": "pluginXYZ", "inject": [ {"models":["X", "Y"]}, {"services": ["xx", "yyy"]} ], //inny plugin, który chce skorzystać z pluginXYZ "use": "pluginXYZ", "inject": [ {"models":["V", "C", "E", "H", "H2"]}, {"services": ["xx", "yyy"]} ] } viewAction($pakiet_models, $pakiet_services); Dopiero po rozpisaniu tego na kartce wyszły ewentualne niedopatrzenia, więc zrezygnowałem z tablic na rzecz kontenerów Kod { "use": "pluginXYZ", "inject": [ {"models": "ModelX_Container"}, {"services": "ServiceX_Container"} ], //inny plugin, który chce skorzystać z pluginXYZ "use": "pluginXYZ", "inject": [ {"models": "ModelZZ_Container"}, {"services": "ServiceZZ_Container"} ] }
Ten post edytował CuteOne 16.11.2012, 12:24:11 |
|
|
![]()
Post
#14
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
1. Po co jakieś dziwne rozgraniczenie na modele i usługi? A jak będziesz chciał wstrzyknąć jeszcze jakiś zupełnie oderwany od nich obiekt? Zresztą usługi pochodzą najczęściej z warstwy modelu.
2. Ponownie - zamiast wymyślać własne rozwiązanie, skorzystaj z gotowego i na 99% lepszego rozwiązania, np. kontenera dostępnego w Symfony2 |
|
|
![]()
Post
#15
|
|
![]() Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
1. Tak jest skonstruowany Zend a nie mam za wiele czasu na tego typu mieszanie w kodzie
2. Coraz bardziej skłaniam się do nauki S2 i stosowania go w późniejszych aplikacjach.. |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 31.07.2025 - 10:34 |