Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Object-oriented programming _ Wstrzykiwanie zależności jak w Spring

Napisany przez: WebCM 3.07.2016, 10:11:58

Podoba mi się podpinanie zależności w Springu. Komponenty tworzymy tak:

  1. @http://www.google.com/search?hl=en&q=allinurl%3Acomponent+java.sun.com&btnI=I%27m%20Feeling%20Lucky
  2. public class MarkdownParser {
  3. public http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky parse(http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky input) { /* kod metody */ }
  4. }

Następnie wykorzystujemy je w tych klasach, gdzie są potrzebne:

  1. @http://www.google.com/search?hl=en&q=allinurl%3Acomponent+java.sun.com&btnI=I%27m%20Feeling%20Lucky
  2. public class NewsController {
  3. @Autowired
  4. final NewsDAO newsDAO;
  5.  
  6. @Autowired
  7. final MarkdownParser markdownParser;
  8.  
  9. @GetMapping("/read/{id}")
  10. public http://www.google.com/search?hl=en&q=allinurl%3Astring+java.sun.com&btnI=I%27m%20Feeling%20Lucky read(@PathVariable int id) {
  11. return markdownParser.parse(newsDAO.getById(id));
  12. }
  13. }

W Phalcon PHP też istnieje wstrzykiwanie zależności, ale w nieco mniej wygodnej formie. Otóż w pliku startowym musimy skonfigurować wszystkie komponenty (oprócz wstępnie dostępnych) w ten sposób:

  1. // Uwaga: jest set() i setShared()
  2. $di->set('markdownParser', function() {
  3. return new MarkdownParser;
  4. });

Klasa MarkdownParser dziedziczy po Phalcon\Mvc\User\Component

  1. class MarkdownParser extends \Phalcon\Mvc\User\Component {
  2. public function parse($input) { /* kod metody */ }
  3. }

Raz zarejestrowany komponent jest widoczny wszędzie i wynika z tego dużo problemów. Ponadto IDE nie wie o tym i bez dodatkowych zabiegów nie podpowiada składni.
  1. public class NewsController extends \Phalcon\Mvc\Controller {
  2. public function readAction($id) {
  3. $this->view->text = $this->markdownParser->parse(News::findFirstById($id));
  4. }
  5. }

Jak zaimplementować podpinanie zależności à la Spring w PHP? Macie jakiś pomysł?

Napisany przez: em1X 27.08.2016, 12:31:49

Do takich celów służą moduły we frameworkach odpowiedzialne za Dependency Injection. Przykłądowo w przypadku Zend Framework 2 jest to klasa Service Manager.

Wystarczy dopisać jakiegoś rodzaju listener, który za pomocą Reflection zeskanuje dodaną do kontenera klasę i poszuka wszelkich adnotacji. Następnie potrzebna fabryka, która przy zwracaniu obiektów danego serwisu podepnie zadeklarowane za pomocą adnotacji serwisy.

Założeniem jest, że adnotowany serwis będzie pobierany wyłącznie za pomocą Service Managera. Wykonanie w kodzie zwyczajnie

  1. $service = new Service();
, spowoduje oczywiście, że zależności nie zostaną wstrzyknięte. Jeżeli zależy Ci na tym drugim, niezbędne byłyby jakieś natywne rozszerzenia do PHP.

Osobiście uważam, że nie powinieneś w ogóle takich adnotacji używać. Wiążesz w ten sposób nierozerwalnie swoje klasy z frameworkiem, podczas, gdy powinieneś starać się oderwać swój kod od frameworka w taki sposób, żeby był łatwo przenoszalny do innego projektu/frameworka i był od niego niezależny. Taka jest definicja dobrego kodu, pomijając oczywiście inne zasady typu SOLID/KIS etc.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)