Jak dobrze obsłużyć cross-cutting-concerns w bibliotece?

0

Piszę sobie bibliotekę T-Regx i teraz chciałbym dodać narzędzie developerskie, które będzie pozwalało zobaczyć dokładnie które wbudowane metody PHP są odpalane.

Tzn chciałbym pokazać że np taki kod

pattern('[A-Z]+')->replace($input)->first()->callback(function (Match $match) {
    return 'foo';
});

pod spodem robi

preg_replace_callback(/* tutaj powsadzane odpowiednie wartości z runtime'u */);

a np. taki kod:

pattern('(Unclosed group')->validate();

pod spodem robi

preg_match_all(/* z wartościami */);
preg_last_error();
error_get_last();

Tak na prawdę chciałbym zrobić logger, z bardzo konkretnymi danymi.



Ale niestety metody których używam są globalne w php. Jedyne pomysły jakie mam (słabe) to:

  • Dodać pole statyczne z zależnością DebugTool z którego korzystałyby wszystkie klasy które mają do czynienia cokolwiek z globalnymi funkcjami PHP
  • Przekazać w dół przez dependency injection zależność DebugTool do wszystkich klas

Ale oba te podejścia mi się nie podobają:

  • Ukryte powiązanie pomiędzy w ogóle niezwiązanymi klasami.
  • Wszystkie klasy w bibliotece teraz są immutable, bardzo ciężko byłoby jakoś "popusć" (nawet powiedziałbym że w aktualnej wersji biblioteki niewykonalne; bo raczej nie modyfikuję stanu). Z dodaniem pola statycznego który trzyma stan popsucie staje się prostsze.
  • Nie podoba mi się że klasy które mają jedną odpowiedzialność (co bardzo sobie cenię w tej bibliotece) nagle dostają DebugTool

Nie chcę też zaciągać żadnych innych bibliotek (ma pozostać 0 zależności). Chcę móc potencjalnie zrobić

// Normalnie
pattern($p1)->match($m)->all();
pattern($p2)->match($m)->all();

ale również

// Na około, tak jak teraz się da
$p1 = pattern($p1);
$p2 = pattern($p2);

$m1 = $p1->match($m);
$m2 = $p2->match($m);

$m1->all();
$m2->all();

Wolałbym też unikać printowania czegokolwiek na standard output.

Macie jakiś pomysł jak sensownie śledzić wykonania metod globalnych? Ale tak żeby przechowywanie stanu było w miarę odseparowane tak żeby można było to wołać wiele razy równolegle, jak w przykładzie powyżej?

0

Podejście w stylu:

Każde ma pewne wady i zalety (czytelność vs zwięzłość) - jestem ciekaw nad potencjalnymi innymi pomysłami ;-)

0
Patryk27 napisał(a):

Podejście w stylu:

Każde ma pewne wady i zalety (czytelność vs zwięzłość) - jestem ciekaw nad potencjalnymi innymi pomysłami ;-)

No tak, to by się wpisywało w mój drugi pomysł, niestety ma problem o którym mówiłem - te klasy musiałyby wiedzieć o trace'able. A nie chciałbym żeby o tym wiedziały :/

0

Dlaczego nie chciałbyś, aby były tego świadome?

Btw, jeszcze inaczej można podejść w taki sposób: https://4programmers.net/Pastebin/11120 (ew. z dekoratorem zamiast interfejsu).

1
Patryk27 napisał(a):

Dlaczego nie chciałbyś, aby były tego świadome?

Głównie dlatego że boje się za chwilę przyjdzie drugi cross-cutting-concern i będę musiał dodać kolejną zależność.

Btw, jeszcze inaczej można podejść w taki sposób: https://4programmers.net/Pastebin/11120 (ew. z dekoratorem zamiast interfejsu).

No właśnie o tym samym pomyślałem! Czytasz m w myślach :D Chyba ten element zastosuję, skoro nie ma innej opcji.

PS: Chyba szukałem gumowej kaczki @Patryk27 - i dzieki Tobie się udało :D Dzięki

0
Patryk27 napisał(a):

Dlaczego nie chciałbyś, aby były tego świadome?

SRP

1 użytkowników online, w tym zalogowanych: 0, gości: 1