yoda Posted February 18, 2014 at 08:20 PM Report #545714 Posted February 18, 2014 at 08:20 PM Boas, Alguém aqui tem aplicado / já aplicou o conceito de Dependency Injection em PHP? O conceito em teoria abre outras portas no desenvolvimento de código sustentável, e torna possível por exemplo desenhar um e-commerce com grandes melhorias em relação à adaptação da aplicação ao domínio / requisitos do cliente final. Seria um projecto interessante desenhar uma framework básica à volta do conceito. before you post, what have you tried? - http://filipematias.info sense, purpose, direction
I-NOZex Posted February 18, 2014 at 09:39 PM Report #545727 Posted February 18, 2014 at 09:39 PM nunca tinha ouvido falar em tal, no entanto fica aqui um link que achei interessante partilhar: http://code.tutsplus.com/tutorials/dependency-injection-in-php--net-28146 B2R » Beat2Revolution v3.0b | Regista e divulga-nos beat2revolution.net
taviroquai Posted February 18, 2014 at 10:05 PM Report #545732 Posted February 18, 2014 at 10:05 PM Tenho ideia de que as duas maiores frameworks Zend e Synfony são baseadas em DI. Para testes unitários, DI é o melhor.
scorch Posted February 18, 2014 at 10:56 PM Report #545747 Posted February 18, 2014 at 10:56 PM Em termos de frameworks já existentes, a única com que já tive alguma e que tem DI foi a Laravel. Pessoalmente, já implementei eu próprio uma variante de Dependency Injection cheio de customizações. Um sistema de módulos com estrutura hierárquica, onde qualquer módulo podia ter sub-módulos, cada módulo tinha um tipo (a classe), e podia pertencer a um grupo (Models, Views, Controllers, Resources, and so on). Em qualquer módulo podia aceder a uma instância de outro módulo utilizando o método load e passando um caminho do género Modulo1:Modulo2. A framework automaticamente, aplicava os alias (mais à frente), e com base nos módulos que já tinha carregados tentava resolver o pedido, e se não estivesse carregado, procurava no sistema de ficheiros pelo módulo (utilizando regras especificas mas bastante intuitivas: não era necessário registar os módulos, mas os seus nomes dos ficheiros determinavam os seus tipos e grupos, e as suas localizações determinavam os seus lugares hierárquicos). os alias permitiam coisas como substituir todos os módulos de um determinado grupo por outro grupo, ou todos pela mesma instância, e esse género de coisas, para além de poderem ter scopes diferentes, ou seja, o alias era aplicado a um módulo em especifico e aos seus sub-módulos. Ainda tinha mais umas funcionalidades, mas basicamente era isto. Atualmente estou a usar essa framework minha no meu projecto de final de curso, e serve bem para as minhas necessidades especificas, mas precisava de algum trabalho extra para funcionar em projectos generalizados. Se tivesse mais algum tempo livre, gostava de reescrever a framework do zero com algum do conhecimento que ganhei entretanto, bem como da experiência de como as coisas deviam ser implementadas, de modo a torná-la mais flexível para outros projectos que tenham necessidades diferentes do meu, e mais extensível. Mas o tempo não dá para tudo. 🙂 PS: Não respondo a perguntas por mensagem que podem ser respondidas no fórum.
taviroquai Posted February 19, 2014 at 01:00 AM Report #545756 Posted February 19, 2014 at 01:00 AM Acho que é importante especificar em que contexto se considera que "uma framework usa DI". Ao nível do core? Ao nível de extensões/plugins? Ao nível da utilização da API? É que a resposta não é lá muito linear... Por exemplo, dizer que a Laravel usa DI... sim o seu Core usa DI e IoC, mas se olhar-mos para a API, http://laravel.com/docs, maior parte das páginas não obriga a que o utilizador use DI (isto com o intuito de simplificar a utilização), alias, a API são umas classes estáticas... (nem ainda vi como é que eles testam isto...) E deixo uma citação... The main issue with static methods is that they introduce coupling, usually by hardcoding the dependency into your consuming code, making it difficult to replace them with stubs or mocks in your Unit-Tests. This violates the Open/Closed Principle and the Dependency Inversion Principle, two of theSOLID principles. You are absolutely right that statics are considered harmful. Avoid them.
yoda Posted February 19, 2014 at 03:33 AM Author Report #545759 Posted February 19, 2014 at 03:33 AM (edited) Tenho ideia de que as duas maiores frameworks Zend e Synfony são baseadas em DI. Para testes unitários, DI é o melhor. O que elas praticam tem outro termo, Service Locator ... é semelhante mas tem diferenças fulcrais, principalmente tendo em conta o Tell, Don't Ask Edited February 19, 2014 at 03:33 AM by yoda before you post, what have you tried? - http://filipematias.info sense, purpose, direction
yoda Posted February 19, 2014 at 03:56 AM Author Report #545761 Posted February 19, 2014 at 03:56 AM (edited) @scorch, essa framework que falaste não parece ter muito a ver com o caso, penso eu .. @taviroquai, Sim, há frameworks com DI de base e outras que o suportam, como CodeIgniter ou Kohana. Laravel tem DI de base mas como qualquer outra framework tentam vender ideias de como as coisas devem ser, e perdem-se aí. Quando falei em framework básica era mesmo básica. Por exemplo um dos problemas que o DI resolve quando devidamente aplicado é que um pedido ajax num site vai obter uma resposta rápida, pois esse mesmo pedido tem poucas dependências, ao contrário do que acontece com a maior parte das frameworks em que o mesmo pedido ia passar pela verificação rotineira estabelecida como defeito para qualquer pedido. DI é bastante simples entender, por em prática requer mais trabalho e atenção, mas a ideia é atingir algo deste género : (exemplo simples, na verdade torna-se mais complexo) $di = new DependencyInjector; $di->register('config', $di->bind(function($c) { return new Config(); })); $di->register('storage.driver', function($c) { return new Storage_Driver($c->resolve('config')); }); $di->register('storage', function($c) { return new Storage($c->resolve('storage.driver')); }); $di->register('user', function($c) { return new User($c->resolve('storage')); }); $user = $app->resolve('user'); // vai chamar todos os outros objectos consecutivamente dos quais depende $user->getAll(); A ideia é um pouco registar todos as instâncias e propriedades "públicas" de forma a ter acesso a elas em qualquer lado sem ter de procurar pelo que se procura explicitamente. No exemplo abaixo a função pede explicitamente o que precisa para fazer o seu trabalho, e o DIC (Dependency Injection Container) injecta, como o nome diz, essas dependências quando a classe / função é chamada. class Controller { private $request; private $response; public function __construct(Request $request, Response $response) { $this->request = $request; $this->response = $response; } } Edited February 19, 2014 at 03:58 AM by yoda before you post, what have you tried? - http://filipematias.info sense, purpose, direction
I-NOZex Posted February 19, 2014 at 11:44 AM Report #545776 Posted February 19, 2014 at 11:44 AM a versão 2.0 da Yii que deve ser lançada dentro de alguns meses, ja vai ter suporte total, pelo que vi no github, mas mesmo atualmente, ja é possivel aplicar o modelo: http://www.yiiframework.com/forum/index.php/topic/40694-yii-dependency-injection-container-tutorial/ B2R » Beat2Revolution v3.0b | Regista e divulga-nos beat2revolution.net
scorch Posted February 19, 2014 at 03:18 PM Report #545801 Posted February 19, 2014 at 03:18 PM (edited) Quando falei em framework básica era mesmo básica. Simples, existe o Pimple, da empresa por detrás da Symfony. Acho que é importante especificar em que contexto se considera que "uma framework usa DI". Ao nível do core? Ao nível de extensões/plugins? Ao nível da utilização da API? É que a resposta não é lá muito linear... Por exemplo, dizer que a Laravel usa DI... sim o seu Core usa DI e IoC, mas se olhar-mos para a API, http://laravel.com/docs, maior parte das páginas não obriga a que o utilizador use DI (isto com o intuito de simplificar a utilização), alias, a API são umas classes estáticas... (nem ainda vi como é que eles testam isto...) E deixo uma citação... Laravel usa Facades, ou seja, apesar de ao utilizador final, parecerem classes estáticas, elas usam o IoC da framework. Ou seja, usando os magic methods do PHP, quando chamas um método de uma classe facade (uma classe estática que extende a classe Facade do Laravel), essa classe apenas serve de mirror para uma instância normalíssima da classe. E como as Facades usam o IoC, não é necessário modificar o código, basta mudar a classe que o IoC resolve. 🙂 More on this: http://stackoverflow.com/questions/19193532/laravel-4-facade-vs-di-when-to-use Edited February 19, 2014 at 03:18 PM by scorch 1 Report PS: Não respondo a perguntas por mensagem que podem ser respondidas no fórum.
rgfdgdfgd Posted February 19, 2014 at 03:46 PM Report #545805 Posted February 19, 2014 at 03:46 PM (edited) Boas, Alguém aqui tem aplicado / já aplicou o conceito de Dependency Injection em PHP? O conceito em teoria abre outras portas no desenvolvimento de código sustentável, e torna possível por exemplo desenhar um e-commerce com grandes melhorias em relação à adaptação da aplicação ao domínio / requisitos do cliente final. Seria um projecto interessante desenhar uma framework básica à volta do conceito. yoda para alguem que ja programa php há anos, não estou a ver que tenhas grande conhecimento de php, principalmente no OOP podes ser expert em remendos ou a inverntar metodologias de programação, que é nisso que o php é conhecido... tu VS um gaijo de faculdade um ano de experiencia que programe software em php asserio vai valer mais que tu no mercado... devias aprender ruby on rails ou django ao menos nessas frameworks não se faz a cagada que fazem nessas empresas de esterco de media e design... quando trabalhas em equipas de 10 ou mais pessoas ja tinhas aprendido e muito, agora a fazer projetos da caca nunca vais aprender muito... se não reparaste o php é um monte de esterco só nos ultimos anos é que comecou a melhorar, dai a denominação "programação dos pobres" já agora programas javascript orientado a objectos, ou fazes formularios da treta com um request ajax todo pipi ? Edited February 19, 2014 at 03:54 PM by fdgdfgdfgd
scorch Posted February 19, 2014 at 03:58 PM Report #545809 Posted February 19, 2014 at 03:58 PM @fdgdfgdfgd No fórum encorajamos um ambiente amigável, de respeito onde todos tenhamos algo a ganhar por aqui participar. Como este é o teu primeiro post, fica apenas aqui o aviso para que tenhas mais cuidado nos teus posts. Todos temos o direito à nossa opinião, mas ninguém tem o direito de tentar rebaixar os outros só para parecer grande. PS: Não respondo a perguntas por mensagem que podem ser respondidas no fórum.
nelsonr Posted February 19, 2014 at 04:00 PM Report #545811 Posted February 19, 2014 at 04:00 PM Olha quem voltou...
taviroquai Posted February 19, 2014 at 07:39 PM Report #545861 Posted February 19, 2014 at 07:39 PM (edited) Bem me parecia que não estamos a falar da mesma coisa... Para mim, uma coisa é DI, isto é, basicamente entre duas classes A e B, A não pode ser instanciada sem B, ou melhor, não faz sentido instanciar A sem B. Sim, já falamos que existem várias formas de "injectar" a dependência, seja no construtor ou num método... Mas isto não implica (ainda) um "contentor". Um contentor é mais à frente... Por exemplo, em MapScript: $map = new ms_Map(); $layer = new ms_Layer($map); // Não faz sentindo instanciar uma layer (camada) sem haver um mapa... Um DI Container, para além de existir esta dependência, pelos exemplos que tenho visto (também do Pimple), aproxima-se mais a uma Registry (design pattern), ou seja, um contentor onde todos os serviços são "públicos" e podem comunicar entre si. É claro que vejo vantagens nisto, especialmente para o programador poder ter vários serviços num único local... no entanto, também vejo uma desvantagem: nem todos os serviços precisam comunicar entre si e conhecerem-se todos uns aos outros e isto pode-se traduzir em consumo de memória desnecessário se a complexidade da aplicação for considerável (nem sei lançar um número... digamos 100 classes). My 50 cents... PS. yoda já tinhas levantado esta questão anteriormente... se calhar não obtiveste aqui uma melhor resposta... 😕 EDIT: Outra coisa que não gosto muito: $foo = $di->resolve('bar'); // como é que eu sei que tipo de dados é $foo??? Nem a IDE vai conseguir resolver por type hint... // old school $foo = Service::BarService(); // ah! $foo é do tipo Bar! Bem melhor... Sim, resolver classes a partir de strings... permite coisas mais dinâmicas, mas será que ajuda o programador que se depara pela primeira vez com este tipo de programação? Acho que não... Edited February 19, 2014 at 07:47 PM by taviroquai
scorch Posted February 19, 2014 at 07:49 PM Report #545874 Posted February 19, 2014 at 07:49 PM Não implica um contentor, mas implica pelo menos uma classe na qual possamos definir as regras (a quais interfaces correspondes quais classes, etc...) e a quem depois possamos pedir os recursos, para que estas tratem de os inicializar, e se estes as tiverem, inicializar as suas dependências, e assim recursivamente. 🙂 PS: Não respondo a perguntas por mensagem que podem ser respondidas no fórum.
HappyHippyHippo Posted February 19, 2014 at 09:40 PM Report #545878 Posted February 19, 2014 at 09:40 PM no entanto, também vejo uma desvantagem: nem todos os serviços precisam comunicar entre si e conhecerem-se todos uns aos outros e isto pode-se traduzir em consumo de memória desnecessário se a complexidade da aplicação for considerável (nem sei lançar um número... digamos 100 classes). eu não vejo as frameworks a funcionar dessa maneira. é de supor que os serviços só são instanciados on demand. isto quer dizer que apesar de estar tudo acessível, a instanciação só é feita quando for necessária a sua utilização e ainda não tiver sido feita anteriormente. IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
scorch Posted February 19, 2014 at 09:45 PM Report #545880 Posted February 19, 2014 at 09:45 PM eu não vejo as frameworks a funcionar dessa maneira. é de supor que os serviços só são instanciados on demand. isto quer dizer que apesar de estar tudo acessível, a instanciação só é feita quando for necessária a sua utilização e ainda não tiver sido feita anteriormente. Exato, é como o HappyHippyHippo diz. Aliás, para além do desacoplamento entre os módulos (e uma consequência disto) é o facto de apenas os módulos necessários serem carregados, pois os outros não estão associados/ligados/conectados. Ou seja, a cada request apenas é executado uma sub-aplicação da aplicação total, ou seja, o benefício é, de facto, proporcional quanto maior for a dimensão da aplicação. 🙂 PS: Não respondo a perguntas por mensagem que podem ser respondidas no fórum.
taviroquai Posted February 19, 2014 at 11:00 PM Report #545892 Posted February 19, 2014 at 11:00 PM Concordo, mas muito graças ao autoloading, independentemente de se usar DI container ou não.
yoda Posted February 19, 2014 at 11:27 PM Author Report #545898 Posted February 19, 2014 at 11:27 PM Outra coisa que não gosto muito: $foo = $di->resolve('bar'); // como é que eu sei que tipo de dados é $foo??? Nem a IDE vai conseguir resolver por type hint... // old school $foo = Service::BarService(); // ah! $foo é do tipo Bar! Bem melhor... Sim, resolver classes a partir de strings... permite coisas mais dinâmicas, mas será que ajuda o programador que se depara pela primeira vez com este tipo de programação? Acho que não... Não é bem essa a ideia, a ideia é ter um $di->user (user autênticado) que é a mesma instância em qualquer parte do script, não ter que adivinhar o que a nossa nova função para um sistema já existente requira (por estar explícito na construção de objectos), poder fazer alterações mínimas no código para testar sem ter de editar 40 linhas para se testar uma delas, ... before you post, what have you tried? - http://filipematias.info sense, purpose, direction
I-NOZex Posted February 20, 2014 at 10:52 AM Report #545916 Posted February 20, 2014 at 10:52 AM é assim, eu tenho tando a seguir o topico, mas a verdade é que ainda nao apanhei XD as vezes sou um pouco lerdo. Alguem pode dar ai uma definição assim por base, para leigos, do que realmente se trata isto, e para que realmente serve, cenarios em que faça logica usar isto... isto quando se é autodidacta há certas coisas que so passados uns anos é que nos deparamos... mas tenho gosto em evoluir, por isso se alguem se quizer chegar a frente e explicar-me, ficaria muito grato 🙂 B2R » Beat2Revolution v3.0b | Regista e divulga-nos beat2revolution.net
KTachyon Posted February 20, 2014 at 02:57 PM Report #545942 Posted February 20, 2014 at 02:57 PM Numa palavra: Decoupling 1 Report “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now