Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rozszerzanie klas korowych
Forum PHP.pl > Forum > PHP > Object-oriented programming
reptile_rex
Witam, mam pewien problem z którego rozwiązaniem już trochę się zmagam i nie mogę znaleźć dobrego rozwiązania.

Mianowicie, przykładowo mam strukturę klas korowych:

  1. Core
  2. - Messages
  3. - Messages.php
  4. - Settings
  5. - Settings.php


Jako, że w przyszłości nie chciałbym wymuszać zmiany tych klas, chciałbym zaprojektować mechanizm Override.
Każda z tych klas dziedziczyła by po klasach korowych i mógłbym w ten sposób zmieniać ich metody (przeciążać) bez ingerencji w kod korowy.

  1. Custom
  2. - Messages
  3. - Messages.php
  4. - Settings
  5. - Settings.php


Nie ma problemu z wczytaniem tych klas ponieważ stosuję schemat PSR-0 i mój autoloader sobie z tym poradzi.

Natomiast problem pojawia się w momencie otrzymania obiektu.
Obiekty są u mnie tworzone w sposób normalny czyli przykładowo:

  1. $object = new \Core\Messages\Messages();
  2. $object2 = new \Core\Settings\Settings();
  3. \Core\Example\ExampleClass::staticMethod();


W rezultacie - ładowana jest zawsze klasa korowa i zawsze zwracany jest jej obiekt.
Chciałbym doprowadzić do momentu w którym ładowany jest obiekt klasy rozszerzającej (gdy ona istnieje) w innym wypadku ładowanie korowej.

Próbowałem już napisać sobie klasę, która zwraca odpowiedni obiekt, taki prosty Loader, który sprawdza czy klasa posiada swój Override.
Jednak jest to trochę uciążliwe podczas pisania, a w szczególności podczas gdy odwołujemy się do klas abstrakcyjnych i ich metod statycznych,
wtedy przykładowo kod musiałby wyglądać tak:

  1. // Jezeli klasa normalna - zwracany obiekt
  2. $object = \Service::Core('Klasa\Klasa');
  3.  
  4. // Jezeli klasa abstrakcyjna zwracana jest przestrzen nazw
  5. $namespace = \Service::Core('Abstract\AbstractClass');
  6. $namespace::oneOfStaticMethod();


Czy macie jakieś inne pomysły na rozwiązanie tego problemu ?

Byłbym wdzięczny za każdą wskazówkę
Crozin
Klasy/kod korowy, mechanizm Override - co to za potworki?!
Cytat
Czy macie jakieś inne pomysły na rozwiązanie tego problemu ?
Problem rozwiązany już wiele, wiele lat temu. Google: Dependency Injection Container - w PHP możesz skorzystać z DIC-a dostępnego w FW Symfony. Jest wystarczająco rozbudowany by nie sprawiać problemów.
reptile_rex
Od razu potworki, tak sobie to ponazywałem wink.gif

Co do DIC to już słyszałem o tym, (Pimple od Symfony).

A wiesz może jak to wygląda po stronie odwołań do klas abstrakcyjnych i ich metod statycznych ?
Bo w przykładach widziałem tylko zastosowanie do obiektów i zastanawiam się czy nie będzie z tym problemów.
Crozin
Do klas abstrakcyjnych nie powinieneś się w ogóle odnosić poza ich dziedziczeniem. Z metod/właściwości statycznych również nie powinno się z reguły korzystać. Jeżeli potrzebujesz takową nadpisać na 95% masz błąd w założeniach/projekcie danej klasy.
reptile_rex
Z reguły nie korzystam z metod statycznych, ale większość moich klas korowych korzysta ze wzorca Singleton
Więc aby otrzymać ich instancję muszę wykonać statyczne getInstance();

Niektóre klasy korowe mają swoje sterowniki/adaptery, które także są "singletonowe", i aby zwrócić odpowiedni obiekt danego adaptera także muszę wykonać statyczne getInstance();
Crozin
Cytat
Z reguły nie korzystam z metod statycznych, ale większość moich klas korowych korzysta ze wzorca Singleton
No to już masz pierwszy poważny błąd w projekcie kodu, a co za tym idzie problemy, których przy normalnym projektowaniu nie byłoby.
reptile_rex
Sugerujesz, że używanie singletona jest poważnym błędem ?
phpion
Cytat(reptile_rex @ 29.12.2012, 12:36:35 ) *
Chciałbym doprowadzić do momentu w którym ładowany jest obiekt klasy rozszerzającej (gdy ona istnieje) w innym wypadku ładowanie korowej.

Code Igniter oraz Kohana w wersji 2 mają coś takiego. Ściągnij i zobacz jak jest to zrealizowane.
Crozin
W niemal wszystkich przypadkach w jakich widzę Singletona jest on użyty niepotrzebnie komplikując jedynie życie. W skrócie: niemal zawsze tak.
reptile_rex
Przykładowo mam klasy obsługujące tablice super globalne POST / GET / SESSION etc.
W tym przypadku nie chciałbym pozwolić na tworzenie nowych instancji tych klas poza głównymi.
Więc użycie singletona w tym wypadku wydaje mi się uzasadnione.

@phpion
CodeIgniter jak i zapewne Kohana, która chyba wywodzi się z CodeIgnitera, posiadają własne Loadery o których pisałem w pierwszym poście, dzięki temu mogą zwracać odpowiedni obiekt
Crozin
Cytat
Przykładowo mam klasy obsługujące tablice super globalne POST / GET / SESSION etc.
W tym przypadku nie chciałbym pozwolić na tworzenie nowych instancji tych klas poza głównymi.
Więc użycie singletona w tym wypadku wydaje mi się uzasadnione.
Idealny przykład obrazujący złe użycie Singletona. Dlaczego niby niemożliwym miałoby być utworzenie dwóch obiektów tego typu? Już pomijam fakt, że przy różnego rodzaju testach będziemy potrzebowali wielu instancji takich obiektów.

@phpion Mechanizm wykorzystywany w Kohanie jest jednym z bardziej porąbanym i niewygodnym jaki w życiu widziałem. Nawet nie sugeruj takich cudów. wink.gif
reptile_rex
Żeby w pełni uzasadnić swoje podejście musiałbym Ci dokładnie opisać założenia i jądro systemu który projektuję, a nie mogę tego zrobić.
Nie mniej jednak zastanowię się jeszcze jakby to wyglądało bez singletona i podejmę decyzję co z tym zrobić dalej.

Dzięki za wszelkie wskazówki
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.