Php dziedziczenie

0

Mam aplikacje gdzie jest core - takie pudełko

gdzie mam przykładowo takie dziedziczenie:
Class Biceps extends Class Mięśnie extends Class Człowiek

i mam x wdrożeń korzystających głównie z core

ale dla wdrożenia nazwijmy to Mutant w Class Mięśnie chciałbym nadpisać sobie jedną z metod np dostarczTlen()

Jak zrobić aby wywołując:

$biceps = new Biceps();
$biceps->dostarczTlen();

Gdzieś w klasach corowych załapało że dla wdrożenia Mutant nadpisało tę metodę a reszta zadziałała "corowo" ?

6

Człowiek MA mięśnie, a mięsień NIE jest człowiekiem. W tym wypadku powinieneś zastosować kompozycję.

Musisz bardziej czytelnie opisać problem, bo te twoje mięśnie i mutanty niewiele mówią. Wygląda to trochę tak, jakbyś miał jeden god object po którym wszystko w Twoim systemie dziedziczy, a to już jest tragedia.

0

Robisz coś źle. Po 1 jak wyżej @Desu napisał, Biceps nie ma nic wspólnego z człowiekiem, człowiek może np. mówić a mięsień tego nie potrafi - a w Twoim kodzie będzie to potrafił - chociaż też wszystko zależy od konktestu.

Co to jest "wdrożenie"?
Co to jest "core"?

0

To jest tylko przykład, być może nie najlepszy.

Chodzi o to że mamy pewne klasy ( załóżmy 3 ) które dziedziczą po sobie.

i mamy xx klientów/wdrożeń (zwał jak zwał)

i część z nich korzysta w całości z tych 3 klas "corowych" ( czyli raz utworzonych ), więc nie wymaga to dodawania niczego w kodzie

ale niektórzy z nich w niektórych klasach mają mieć pewne modyfikacje, ale nie chce kopiować całych klas ze wszystkimi metodami do poszczególnych klientów, chciałbym żeby u danego klienta dodać tylko określone metody które będą inne ( choć przyjmują i zwracają zmienne analogicznie jak te corowe)

Czyli np dla aplikacji Y dopisuje jedną metodę która jest już w core ale jeśli odpalam aplikacje Y to php ma skorzystać z niej a nie z tej która jest bazowa/core

2

Brzmi jakbyś miał aplikację, która nazywa się multi-tenant application. Według mnie potrzebujesz wzorca strategii, ale i tak nie czuję, że dobrze rozumiem temat. Wtedy dla każdego klienta tworzysz sobie konfigurację i komponujesz ją z odpowiednich strategii.

Tak na dobrą sprawę sama strategia może nie wystarczyć, bo żeby zaproponować jakieś konkretne rozwiązanie musiałbym mieć dużo głębsze zrozumienie problemu.

Gdzieś w klasach corowych załapało że dla wdrożenia Mutant nadpisało tę metodę a reszta zadziałała "corowo" ?

Pamiętaj o LSP. Klasa dziedzicząca nie powinna zmieniać kontraktu i nagle robić coś innego niż zakłada klasa bazowa.
https://en.wikipedia.org/wiki/Liskov_substitution_principle

nie chce kopiować całych klas ze wszystkimi metodami do poszczególnych klientów, chciałbym żeby u danego klienta dodać tylko określone metody które będą inne

Tutaj z pomocą przychodzi ISP i kompozycja oraz wyżej wymieniona strategia.

https://designpatternsphp.readthedocs.io/en/latest/Behavioral/Strategy/README.html

0

Tu wzorzec strategii nie do końca zadziała bo wszędzie bym musiał robić te switche przy każdej modyfikacji, dla kilku przypadków to nie jest problem ale jak aplikacji są dziesiątki i modyfikacji też to nie zatrybi. https://zawarstwaabstrakcji.pl/wzorce-projektowe/strategia/

Mam wrazenie że php nie obsługuje takiego przypadku bo jedyne co mi przychodzi na myśl jako rozwiązanie to:

jeśli odpalam aplikacje X która nie ma nadpisanych żadnych metod to wszystko działa corowo i nie ma problemu

jeśli odpalam aplikacje Y która ma nadpisaną jedną(lub więcej) metodę w którejś z klas to jeszcze przed wywołaniem php w "locie" jakiś skrypt tylko dla tego wywołania zastępuje metodę corową tą z aplikacji Y

2

Być może jakiś framework do aspect oriented programming w PHPie by się tutaj sprawdził, lecz wtedy ucierpi wydajność oraz czytelność - jak dużo tych nie-corowych aplikacji macie?

0

setki

Chyba że bym jakiś automat napisał który by wykorzystał to:
http://php.net/manual/en/function.runkit-method-redefine.php

1

Redesign aplikacji wchodzi w grę?
Przeważnie takie sprawy rozwiązuje się np. mechanizmem eventów i sprawdza się całkiem nieźle.

0

no sam napisałeś że chodzi o dziedziczenie, więc zamiast zmieniać tą samą klasę dla różnych klientów, zrób klasy dziedziczące np . BicepsaMutanta dziedziczący z Biceps i w zależności od klienta używaj innej klasy potomnej, zamiast kombinować z zmienianiem metod w locie

1

@zergeling: nie do końca musisz robić te switche. Wszystko załatwiasz plikiem konfiguracyjnym i interfejsami. Nie musisz mieć nawet jednego if'a. No może jeden, który sprawdza dla kogo działa apka i wczytuje odpowiedni plik konfiguracyjny.

Załóżmy, że masz jakiś moduł e-commerce. Masz klasę, która zajmuje się liczeniem ceny zamówienia. Możesz mieć w niej metodę calculate. Metoda ta w podstawowej wersji sumuje ceny produktów * quantity. Teraz powiedzmy, że klient A ma jakieś reguły zniżkowe. Klient B też, ale są one całkowicie inne. Reguł może być 500. Ty chcesz stworzyć klasę PriceCalculatorWithDiscount, PriceCalculatorWithDiscountForCustomerA, PriceCalculatorWithDiscountForCustomerB... itd. i w każdej "delikatnie nadpisać" działanie metody calculate.

Bez sensu. Lepiej jest każdą regułę wydzielić do osobnej klasy. Teraz w pliku konfiguracyjnym dla klienta A definiujesz reguły, które będą wstrzyknięte do Twojej klasy i tyle. W runtimie symfony czy inny framework załatwia wszystko za Ciebie. Patrzy dla jakiego klienta działa apka i buduje Ci te twoje obiekty, tak jak masz w konfiguracji.

Dlatego zazwyczaj jak się ma jeden produkt, to nie słucha się każdego pierdnięcia klienta, bo powstaje Ci miliard ficzerów specjalnie pod klienta, a to generuje mnóstwo problemów. No chyba, że klient bardzo dużo płaci.. to wtedy można.

Możesz też stworzyć core aplikacji i jak któryś chce coś turbo customowego, to budujesz aplikację pod niego wychodząc z core'a. Jak jakiś ficzer, który sobie zażyczy wydaje się fajny i w miarę uniwersalny, to dopiero wrzucasz do core'a.

TD;DR;
Nie podamy Ci dobrego rozwiązania Twojego problemu bez bardzo dokładnego wejścia w jego domenę i biznes. Ogólnikowo to strategie.. fabryki.. AOP.. plug-In architecture.

Możesz też spróbować zobaczyć jak ogarnął to wordpress albo presta lub magento.

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