DrupalCon Portland 2013

Inyección de dependencias en Drupal 8

Katherine Bailey  · 

Presentación

PDF (pincha para descargar)

Vídeo

Transcripción

Extracto de la transcripción automática del vídeo realizada por YouTube.

welcome to dependency injection in Drupal 8 my name is kat bailey i've been working with drupal since 2007 and i got involved in core development a little over a year ago and since then have been helping out a little with the whiskey initiative the web

services and context core initiative that's the initiative that's been mostly responsible for getting a lot of the symphony components into Drupal core okay so just a couple of things before I get started I will be assuming a rudimentary understanding

of object-oriented programming as in i'll assume you know what I'm talking about when I when I'm talking about things like classes and interfaces and constructors but you know if the only experience you've had with object-oriented programming

it's maybe writing custom views handlers or something like that that's totally fine the examples will be very simplistic the other thing I wanted to say is you've probably been hearing about the huge changes in Drupal 8 that are like just so fundamental

and just bigger in nature than the kinds of changes you'll have seen between other versions of Drupal but what I would say is that one of the major drives with the kinds of changes we've been making is towards more standard ways of doing things and

getting away from Drupal isms and certainly with dependency injection learn you know you'll have to learn it for Drupal 8 but that's going to stand to you no matter you know wherever you your programming career takes you beyond Drupal 8 so what I'm

going to cover I'm going to start by looking at dependency injection as a design pattern as a way of structuring classes then move on to looking at how frameworks support dependency injection before getting more specific and looking at a symphony style

dependency injection and then looking at what we're actually doing in Drupal so the first item their dependency injection is a design pattern that's all about why you know as in Hawaii should you care about dependency injection and what problems does

it solve for us and the rest of them is all about how like how how do framework support this so quiet appendices well normally when the topic of dependency injection is introduced you'd start off with an example of some object oriented code where which

isn't doing dependency injection and look at the kinds of problems that can arise but I thought have made more sense to take a bit of a step back seeing as we're not all out going to programmers here and just think about what sort of what sorts of

common goals we might have when we're writing code so i think we can probably all agree that when we write code we want it to be clutter free reusable and testable now what I mean by clutter-free is just you know when you're writing a function you

want it to be to the point and not going off on tangents you don't want to have lines of code that aren't central to what that function is all about I'm going to see some examples of this in a moment reusable obviously you know when you go to the

trouble of writing a function to do something awesome you want to be able to use it over and over again in different contexts and very closely tied to that probably the first context you want to use it in is within the context of a test we want to be able

to test the code we write so we'll start by looking at an example of some procedural code that kind of does it wrong this is a totally contrived example it's very silly function that doesn't do anything interesting but you see the first line of

the function body their loads and include file from a module because it knows that it's going to have to that's where the function is that it calls on the next line that module load include that's an example of clutter like it happens to be necessary

clutter but this function isn't in the business of loading files so that's clutter as for reusability obviously this can't be reused outside of the context of a bootstrap Drupal and it's very closely tied to whatever this other module does

for it so it's not great it's not clutter free it's not not easily reusable and it's not easily testable like if you wanted to test this function you'd either have to have a bootstrap Drupal or at least load the file where module load include

is defined so let's now look at the sort of classic example of doing it wrong an object-oriented code again a fairly contrived example this is a notifier class that we off and its main sort of thing that it does is the notifying method which during the

course of whatever it does it uses it sends an email and it uses an email or object to send that email and how it gets that you see in its constructor it instantiates one for itself at first glance it doesn't look like there's an awful lot of clutter

going on here but that line where it's instantiating a mailer object that new mailer we could see that as clutter because you know this class should not be in the business of loading and knowing how to instantiate a mailer object because you know what

if it's not that simple maybe the mailer actually takes various parameters and if those parameters change like if anything about the mailer class changes well then this class is going to have to change accordingly so we say that it's tightly coupled

to the manor class and that's bad in terms of reusability then you know what if you wanted you didn't want to use the mailer class as the class that sends the email you wanted to use something else and then obviously testability right you prefer to

use a mock mailer something that's not actually going to send an email but here we don't have a choice we're being forced it's it's going to instantiate a mailer object whether we like it or not so what can we do about it the only difference

here you'll see rather than instantiating a mailer in its constructor it takes one as its constructor parameter and so now it doesn't need to know how to instantiate the mailer now it's worth just transitioning back and seeing the difference between

that instantiating the thing in its constructor and that receiving it as a constructor parameter that's dependency injection all right that's all it is so like as one guy put it in a blog post i read recently dependency injection is a 25-dollar term

for a five-cent concept like you're just passing the object it's instance variables as constructor parameters or if you want to be really fancy about it you're injecting it with its dependencies so here I've just put the calling code at the

bottom so the thing that's going to instantiate the notifier first it's going to instantiate a mailer object and then it passed that into the constructor so if you've reframe this in terms of the goals that we had about writing code that's

clutter free reusable and testable another way of thinking about that is we want to write code that's ignorant quite ignorant so the last year code knows the more reusable it is and if you think about it the more your code nodes like the more it knows

about other classes and how to instantiate those classes the more dependent it is that that knowledge that it has stays the same and that's that tight coupling that we want to get away from so let's look at this again and think well what does the notifier

class really need to know about the thing that it's going to use to send the email does it even note need to know what the concrete classes that gets injected into it it doesn't all it needs to know is that it's going to get a thing on which it

can call the send method and pass these parameters and so the way we express that is it'll accept anything that implements the mailer interface so now at the bottom you can see instead of instantiating a mailer object we we use a special Manor and pass

that in instead so that is constructor injection one form of dependency injection so the calling code at the bottom is injecting the mailer into the notifier and you can see the constructor at the top is expressing its dependency on anything that implements

the manor interface so dependency injection is about declaratively expressing dependencies in the class definition rather than instantiating them in the class itself so it's about having classes that are just kind of saying like I need these things to

do my job so you know you're going to have to call me with my dependency if you want me to do anything constructor injection is not the only form of dependency injection it's the most common and it's certainly by far the most common that we use

in Drupal but there are some other forms another common form is setter injection so with setter injection rather than injecting things in the constructor here we have a setter method set mailer that again accepts anything that implements the manor interface

and so you're calling code after instance stating the object will need to call the set mailer method and pass in the dependency so that setter injection there's also interface injection which is very similar to set our injection it's just that

for every setter method that you have for a dependency that's there's an interface for that so it's like the class basically declares itself as being mailer injectable for example it's very verbose because for every set or method you you need

to have an interface and it's not very common I don't think there are any frameworks that actually support interface injection you'll often hear dependency injection referred to as inversion of control these two terms are synonymous and I don't

know about you but when I first heard that it wasn't immediately clear to me why why it was called inversion of control I mean I could I saw there was some kind of inversion going on but it wasn't crystal clear until I read one particular explanation

of it which I've Illustrated here so traditionally you might have a library of classes that your code makes use of so your code is going to call out and instantiate objects from that library of classes and in this setup the library is passive it's

[ ... ]

Nota: se han omitido las otras 5.047 palabras de la transcripción completa para cumplir con las normas de «uso razonable» de YouTube.