Како услугите влијаеле на однесувањето на вбризгување на зависноста од развивачите - Блог на Flagbit

Барем од постојаната растечка популарност на единичните тестови, особено преку PHPUnit, решавањето на зависностите на класи преку вбризгување на зависност во PHP играше сè поважна улога во секојдневниот живот на развивачите. Класите што имаат една или повеќе зависности од другите типови на класи се пренесуваат кога тие се креираат преку конструкторот или преку методни повици при извршувањето. Ова ја подобрува одржливоста на одделните класи и зависностите можат полесно да се разменуваат доколку се променат барањата. Подобрена е и тестираноста на одделните компоненти, во кои зависностите од класа може да се заменат со едноставни двојни тестови. Како неповолност, сепак, се забележува зголемениот број на код на плочата кога секогаш треба да се создаваат исти предмети во различни точки од проектот за да се опфатат истите зависности.
Таканаречениот локатор на услуги беше воведен со сегашните рамки на PHP. Задачата на локаторот на услугата е да ги реши и инстанцира зависностите од услугата внатрешно. Ова значи дека инстанците на предметите можат да се креираат со употреба на услуга без да се додаде кодот на котларата за да се решат зависностите во деловната логика. Понатаму, локаторот на услугата обезбедува единствена инстанца на повиканата услуга во рамките на едно барање, со цел да се избегне непотребно создавање на предмет без недостатоци на класичен единец.
Со текот на времето, леснотијата на користење на Локаторот на услуги ја насочи употребата на вбризгување на зависност во насоки што можат да се спроведат брзо технички, но кои не ја следат нејзината цел. Распуштањето на зависностите се претвори во шарено спојување на часовите.
Подолу, би сакал накратко да ги претставам случаите на кои сум наишол одвреме-навреме. Обично овие можеби не изгледаат погрешно на прв поглед, но може да имаат недостатоци во понатамошниот развој.
Инјекција на локаторот на услугата
Веројатно најпознатата лоша навика при употреба на А. Локатор на услуги е да се додаде ова како зависност во нејзината класа. Обично придружено со аргументот „Можеби сè уште ми треба некоја од услугите“, овој образец е повеќе знак дека некој не планирал доволно во неговиот развој. Ниту една класа никогаш не им е потребна на сите услуги. Понекогаш, исто така, можете да најдете коментари на Google кои сметаат дека е во ред ако на фабрика и се даде Локаторот за услуги Дури и на фабрика и требаат малку услуги за да функционира. Ако постои зависност од повеќе од 4 други услуги, треба повторно да размислите за задачата и структурата на фабриката.
Комплексноста е особено очигледна во пишувањето на единичните тестови. Класата може нормално да се користи за да се идентификуваат зависностите од методот на глава на конструктор или метод на поставување. Кога ќе се додаде локатор на услугата, тест двојно не само што мора да се создаде за него, туку и за сите вистински зависности што се преземаат од него. Исто така е тешко од кодот да се каже кој е вистинскиот вид на услуга. Бидејќи класа во PHP може да содржи и методи кои не доаѓаат од интерфејс, заменливоста на класи со ист интерфејс повеќе не е загарантирана.
Идеално, зависностите треба да се пренесат и да не се земаат од друг објект.
Ако ја погледнете Symfony 2, на пример, ќе видите дека Локаторот за услуги се користи и директно тука. Најпознати примери се контролорите и командите, но само ако тие го имплементираат интерфејсот ContainerAware, што е случај како стандард. Но, постојат опции и за контролорите и командите за да се избегне ова.
Сеча
Запишувањето информации може да биде поважно за еден проект отколку за друг и може да се разликува во количината на информации. Затоа, често постои пристап за трајно вметнување на инстанца на логер како зависност во услугата на класа. Меѓутоа, во многу малку случаи, дрвосечачот е навистина зависност, затоа што прво треба да си поставите прашање: „Дали мојата карактеристика сепак ќе работи без дрвосечачот?“
Во зависност од одлуката за дизајн, може да биде доволно да се фрли исклучок во класата и да се додаде запис во блокот за улоги покрај управувањето со грешки.
Друга можност е да ги соберете пораките за да ги добиете подоцна, како што е познато од валидаторите, на пример. И тука, записите во дневникот може да се креираат надвор од класата и со тоа да се извлече дрвосечачот како зависност.
Додуша, тоа не е грубо кршење на зависноста, но ако е лесно да се држи дрвосечачот надвор од класа, тогаш инвеститорот треба. Тоа е непотребна компонента во автоматските тестови и е ирелевантно за функцијата на класата што се испитува.
Премногу зависности
Секој што гледа на многу зависности кај конструкторот на нивната класа и се чувствува непријатно со нив, веројатно го препознал проблемот. Едноставното ракување со конфигурациите на услугите го олеснува додавањето на нови зависности, бидејќи инвеститорот обично не треба да се грижи за добиените промени при креирање на примери. Бројот на зависности може да расте како што напредува проектот, создавајќи сложеност што не сака да ги допира и менува.
Многу контејнери за вбризгување на зависност нудат можност за поставување на зависности од услугите користејќи методи за поставување во конфигурацијата. Како резултат, некои развивачи имаат тенденција да ги поставуваат зависностите користејќи методи на поставување наместо конструкторот, но ова не го решава проблемот. Напротив: Поставувачите треба да бидат поставени експлицитно и само кога предметот веќе постои. Конфигурацијата на услугата прифаќа употреба на поставувачи, но оваа класа може да се користи само со знаење на овие поставувачи, на пример, за единици тестови, и ако не се поставени задолжителни зависности, инвеститорот исто така мора да се погрижи за ракување со грешки . Ова непотребно ја зголемува погодената класа. Ништо од ова не е потребно со вбризгување на зависност преку конструкторот. Па, како треба да се реши овој проблем?
Тоа е добар знак дека часот прави повеќе отколку што треба.
Во овој случај, нивните задачи треба да се поделат, што потоа ги претставува реалните зависности на оригиналната класа. Не може да се исклучи дека самата оригинална класа повеќе не е потребна и затоа не е применлива, бидејќи нејзината единствена задача е да ги извршува задачите на нејзините зависности.
Резолуција на зависности
Не секоја зависност мора да се реши преку конфигурацијата на услугата, а камоли директната зависност за класа воопшто. Како и да е, овие се вметнуваат преку конструкторот преку услуга. Брзата и лесна конфигурација на услугите значи дека промените може да се направат брзо без да се менуваат местата во кодот што ја повикуваат услугата. Ова го поканува развивачот да реши сè во врска со конфигурацијата на услугата за погодената услуга.
Во следниот пример, класата Foo има зависност од $ myService, што се пренесува во конструкторот.
Во примерот, сепак, оваа зависност се користи само во методот doSomething. Доколку зависноста не е потребна од самата класа, туку само од еден од нејзините методи, треба да се разгледа дали следниов пристап може да биде подобро решение:
Недостаток: Часовите што користат Foo и неговиот метод doS Something имаат зависност од $ myService.
Како втор пристап, исто така, мора да се разгледа дали задачата на методот doSomething не спаѓа во својата класа и мора да биде конфигурирана како посебна услуга. Сепак, оваа нова услуга не мора да мора да биде зависност во класата Foo.
Во овој пример код, задачата на методот doSomething е целосно отстранета од Foo класата и е имплементирана во нова класа „Qux“, која како услуга зависи од $ myService во претходниот пример.
Се разбира, овој пример е едноставен, бидејќи во случај на рефакторирање има и други пречки на патот. Кога се менува структурата на часот, промените мора да се направат на сите места што користеле Foo. Промената на структурата на класата е уште потешка ако е одредена со интерфејс.
Инјектирање на зависност и услуги
Инјекцијата на зависноста е термин за чадор кој има многу различни форми на имплементација. Одлуката која од формуларите треба да се користи во конкретен случај не може да биде донесена од контејнер за инјектирање зависност или локатор на услугата, но за тоа треба да одлучува самиот развивач. Рамките ни нудат функционалности кои ни помагаат во развојот и треба да намалат многу заморни чекори. Како се користи, сè уште зависи од нас.