 Good afternoon, that was a nice little break wasn't it? I didn't realize there was beer out there until about two minutes ago I feel gypped So how are you guys enjoying Prague so far? Good hands up if you enjoyed the conference so far Hands up if you didn't That's a good sign. All right So I want to talk to you a little bit today about object-oriented design object-oriented programming How many here show of hands how many of you practice object-oriented programming right now? That is awesome. How many of you have heard of object-oriented programming? Okay, and how many of you have no clue what it is be honest Wow, nobody that's impressive Yeah, well I'll give you a hint if you don't know what it is. You're gonna have an easier time with the first part of this talk So there's this question what is an object and I think most people get this wrong and I think that the way that we teach object-oriented programming is wrong So let's go through this for a second In the classic view in what we teach in textbooks and you know articles online They try to equate this notion of an object or a class to some kind of a physical thing Your methods make that physical thing do something and then your properties describe that physical thing so you can have a car class and this car class has a method called drive and a method called start and a method called stop and the properties are the car is red the car is a you know Ferrari the car is manual transmission yada yada yada yada all the way down the line and This is popular because it allows you to conceptualize you interact with a car. Maybe not a Ferrari, but you interact with a car every day You don't interact with these magic things called objects So by equating one-to-one we can kind of mentally make a map and that's why people think this is a good idea So we usually wind up with a tree like this. How many people have seen something like this before pretty much everybody You have this inheritance tree this hierarchy where you have an interface animal and Then mammal extends from animal and then cat extends from mammal and then lion extends from cat Makes sense right kind of maybe not really Let's look at what a lion is. Let's talk a little bit about this lion In classic code we may have something like this Does this make sense does everybody understand this or I've seen something like this before? Well, this raises a couple questions is it realistic. Have you ever seen real application code that looks like this? I know I haven't and The reason is let's dissect this What does it mean to make a new lion? What does that first line mean? I? Could go digging through the source code, but mentally in my mind. I think you need two lions in about nine months to make a new lion So when you call new, what does that mean? I have no idea Okay, what does it mean to make a lion roar? Is there some magic button somewhere on the lion where if I press it in just the right way he'll start roaring? What does it mean for an object to hunt? We can probably come up with a scenario where this exact code would make perfect sense But by itself it makes absolutely zero Because we don't know what a lion is in relation or application You need to understand the entire application in order to understand this lion in this little piece of code And that's not what object oriented programming is about Object-oriented code programming is about letting us ignore the rest of the application So this classic model is very easy to understand Which turns out to be both a good thing and a bad thing because it's also completely impractical So let's introduce a new view the what I'm going to term modern view Which is that an object is really a collection of related behaviors Behavior is what we're dealing with here. Your method is the behavior that you want to interact with and Your methods are your behavior Or I'm sorry your methods are your behavior and properties are the details behind that behavior So they may be dependencies. They may be some state information you need to keep track of the key here though Is its behavior that we're dealing with? In the classic view we're talking about an object conceptually is a something So an object conceptually is a lion an object conceptually is a car The modern view is really behaves as a So let's walk through an example with some real code Let's talk about numbers Numbers are a pretty abstract concept Yeah, when we think about them, we normally think about integers or Decimals or things like that, but Roman numerals or complex numbers There's really a lot of broad things that fit this concept of a number so we could talk about this entire hierarchy of types of numbers and Inheritance and all these things that behave as this conceptual number but There's a difference here We don't need inheritance to talk about object oriented programming That tree model is a distraction All we need are polymorphism and encapsulation So it's really really simple Polymorphism is when you have behavior that is dynamically determined Meaning when you call a function in procedural programming You can go look up that function name and know exactly what it does when you write the function You know exactly what it does Polymorphism says we're gonna have some kind of a variable that's gonna control Where that function lives so when you write the code that calls it doesn't know at that point in time What's happening? It's a really really really simple concept. It's really difficult to explain well So we have like a block of procedural code with that number example And we have four different statements here or three different if a is a long integer We do one thing if it's a float we do another if it's a decimal we do another So we have this flow here the problem comes along what if I change add a new type What if I add a complex number or if I add a Roman numeral or something like that Now I need to change my calling code Whereas if we use polymorphic code We're telling the integer what we want to happen. We're saying hey number Add one to yourself. I don't care how that's not my worry. My worry is to tell you what to do You worry about doing it. That's polymorphism Your code looks really simple and that's the whole point of this. We want to localize our code and We can do the same thing with it flow as we did with the integer and it really looks the same just some minor details changed This is something that you really need to play with to really really get a good grasp of So I would suggest trying just trying playing with this try instead of using a raw function call Try making it an object and try changing which object that is So the other half was encapsulation Where behavior we want to hide the information that we're dealing with we want to hide details so we can expose abstractions So the example here is we have a detail that five is stored in the number property of this object If five is the value print the number is five if not print the number is not five This is dangerous because what we're really doing is we're coupling this code to the details behind how number is written Instead we can use a different Concept where we don't ask we don't ask for what your value is We say I want you to tell me if you're equal to to five We're encapsulating those details. We're encapsulating the information Make sense So one of the reasons for this is well for integer and flow. It's pretty easy to do But if we wanted to do a decimal we now have some complex storage so that value property doesn't really exist anymore So now our encapsulated code is safer and we can start to deal with them as containers Bacon so I want to talk about APIs for a few minutes if you were in the last talk that was in this room Larry talked quite a bit about APIs Krell I want to talk about APIs at a fundamental level There's really two fundamental types of APIs You have an interface, which is what they're called in PHP, which is what they're called in Java Way and go in a whole bunch of other languages Which is an explicit API. It's saying I'm gonna give you an object that implements this interface Which means it's gonna have these three methods that hopefully do what we promise them to do The point being is that it's explicit It's just as if you signed a contract that says I guarantee this code is gonna do what I say it's gonna do The other type is duck typing Which is if it looks like a duck, it's probably a duck You pass in a object. We expect it to have a particular method if it doesn't have a method We're just gonna error out. We don't care about the contracts. We don't care about The explicitness of it now to be completely fair I used to be a Interface everything person if you talked to me two three years ago Interfaces are the way to go duck typing is stupid. Why would you do that? Today I'm very much in the middle a lot of my code does have interfaces a lot of my code doesn't It's really different tools for different different uses So now this raises a question If an object is a collection of behaviors What is a collection of objects? What is a collection of classes? As it turns out We have what's um, we have a fractal design a fractal pattern coming out here We have a method which we've already said is behavior, right? Well collection of methods is a class or an object Which is just behaviors Well, what are a collection of classes? Well, we can roll up related classes or related behavior into a package And we can roll up related packages into a library and we can roll up Related libraries into a framework now this happens every day in Drupal code You have a method or a function that you roll up into maybe a file Or classes in Drupal some Drupal 7 code some Drupal 7 modules You have a couple classes that wind up becoming a package and an example of this would be let's say you have an admin section to your Module and you have an admin component within your module that you install that would be a package It's a collection of responsibilities. It's a collection of behaviors that have a single purpose Then you collect a couple of those things you wrap it up into a library that you call a module and then you wrap up a whole collection of modules and you call it a Distribution or eventually a framework like Drupal, which is nothing more in the collection of modules Now the reason I bring this up and the reason that I'm kind of running on a little bit about this all of object-oriented design and the power of object-oriented design is That we can treat a single object the same way we treat an entire library or entire application All of the things that we're going to talk about today are just as applicable at the top level as they are at the bottom level and Everywhere in between and good object-oriented code lets you forget About the bottom half and just worry about what you want to worry about So now what? Let's talk about what makes a good API a good API does one thing Simple a good API never changes Has anyone here worked with the Facebook APIs? Have you magically seen them stop working one day bad a good API doesn't change if it works today. It should work tomorrow a Good API does what it says it does it behaves like its contract a good API has a narrow responsibility Now the first one in this one the single responsibility and narrow responsibility sound Like they contradict or why would you need both? Well, let's say we had of a class and We're going to say its responsibility is to be Drupal That's a pretty wide responsibility. You're going to wind up with a gigantic class Whereas here we can say you do one thing and being a CMS may be one thing But that one job should be very very very narrow it should be very focused a Good API depends upon abstractions because we want APIs to talk to each other We don't want to depend upon implementation details And that's really solid That's what the acronym solid is all about. That's what good object-oriented code is all about So let's go back through these one by one and dive a little bit more in deep So a good API does one thing in solid terms. This is known as the single responsibility principle relatively straightforward now imagine I come to you and I say you're a industrial designer you're a Mechanical engineer and I say I want a multi-tool Okay, what's a multi-tool? Well, I want every tool I could possibly need into one device You may wind up with something like this Which is really only good at two things There's tweezers in there in case you get a splinter and it's good as a paperweight to indicate that you have far too much money to spend Instead you can have narrow focused Responsibilities where you have a set of different hammers and every single hammer is designed for its job It has one reason for being and this is what we want our objects to be we want them to have one reason for being one reason for changing a Good API never changes more formally the open closed principle Objects should be open for extension But closed for modification So if you were going to put on a hat Would you do brain surgery? Probably not you put on the hat But now we can put on two hats and we can do a whole bunch of things And we see this with Photoshop a lot You have a picture and Someone decides well we want to extend this picture. So they make Karl Marx and Then someone else comes along and says you know what no we need a superhero programmer. So they make that programmer Which then becomes kind of a problem because Photoshop has a tendency of reoccurring in real life and then you get this But that's kind of a distraction So continuing on The next one you have is least golf substitution principle Fancy name really really really simple concept This is a US outlet Circa 1920 To prongs you get electricity from one it returns on the other the old European plug is basically the same thing Well, this worked fine for 20 or 30 years until all of a sudden they realized hey, you know what we need a ground pin We need a third pin So rather than making a new plug which a lot of people did they decided we're going to extend this We're going to add a separate pin So now anything that the parent could accept all plugs that worked on the parents still work on the child But we've added functionality That's what the least cost substitution principle is when you're going to change something change it So it still works like the original but add in the new functionality on the side And then you get crazy little contraptions like this The interface segregation principle we want a narrow API. We want a narrow interface If we want to design a multi-tool That is a you know keeping your pocket and use it You keep each interface each thing that it does very narrow very well defined Make it easy to use make it easy to understand and Finally a good API depends upon abstractions. Well, what does that mean? I'm hoping most people have seen a screwdriver like this where you have these all these different bits This is really interface. I'm sorry. This is really dependency inversion at its heart You have the handle which is a detail that I'm going to use my hand to turn. That's a detail It depends upon this socket over here as an abstraction So really those two are connected Then each one of these bits has a detail at one end and an abstraction at the other and when the two abstractions meet You have a useful tool and you can swap either side out. You can swap in different bits We want to depend we want our code to interact with abstract concepts And you can tell if an abstraction is good if it's reusable So these very same bits work just as well in a hand screwdriver as they do in a machine gun So that's solid Remembering the names is harder than remembering the principles It's really really simple and really straightforward And it's useful to note that Solid doesn't dictate what good object-oriented code is Good object-oriented code tends to be solid Solid tends to emerge from good object-oriented code This is really something that takes time. You have to write a lot of code You have to play with a lot of code. You have to look at a lot of code to really truly understand this stuff And that's what I suggest you do Try it, play around with it, write some objects, write some simple little libraries and play Because playing is fun And we all deserve a little fun So what makes a bad API? We've talked about good APIs and solid. Let's talk about a little bit about bad code Global variables are bad Spooky action at a distance There's a story about a guy who came in to test a payment gateway payment system like a shopping cart and He's testing the credit card validation logic Nothing else just the little piece of code that validates the credit card So he's like well, I need a credit card number. I have my credit card number Let me just put my credit card number in there and because of the way the application was structured He had to put a price on it so he put ten cents Ran the test it passed everything came back green. Okay, great. I'm fine I go off I do my other thing a couple weeks later He checks his credit card bill and he's got several thousand dollars worth of charges He goes what the heck is going on and he notices there are all these little ten cent transactions What he realized is he started going through the code and the validation logic actually charged his credit card What should have been a regular expression or something else actually had spooky action in That it did something that he didn't realize was going to happen global variables are bad Depending on the specifics of an implementation Is bad we want to depend upon details one. I'm sorry we want to depend upon abstractions Hidden dependencies similar to spooky action at a distance hidden dependencies are a problem and Unhealthy focus on performance now. This does not mean performances does not matter This means performance only matters after the other important things are checked off Poorly named API's we want names to be good. We want names to be readable And duplication is a problem So that's stupid now again, let's go back through each one so single tins Single tins are not object-oriented code Let me say that again single tins are not object-oriented code Single tins are global variables their procedural code that some people think are object-oriented because it uses objects It's not there a problem So to explain this how many people know what this is Lord of the Rings So the backstory on this ring I find fascinating because it really is single tins and what single tins are This Dark Lord decided one day that he was going to craft a whole bunch of rings of power He gave and I'm going to get these numbers wrong But three to the elves five to the dwarves and seven to men or something like that And he gave them to them as gifts and in secret he crafted this ring to Control all of those others that he gave out So each one of the individual actors each one of the men and dwarves and elves got this ring that they were saying Okay, this makes me powerful But there was a spooky action. There was a single tin in the background, which was this ring controlling it Single tins are not a good idea. We want flexibility. We don't want hidden control Tight coupling. We don't want to depend upon specifics. We want to depend upon abstractions so if we're going to build a car and we need to make an exhaust manifold We don't custom make an exhaust manifold at least Unless it mates up in a standard way because what happens if it breaks? What happens if it's no longer suiting your needs? You can't go and take one off the shelf you have to completely rebuild it And that's kind of some of the part of the problems that you'll see in code Is that when you go to try to fix something small over here if you're too tightly coupled something big breaks over here? Wait a minute. I changed something in the user profile and search broke How why are those two things connected in the first place? Untestable code. We don't want to have hidden dependencies We want to have our code written in such a way that's easily testable Now I'm a kind of like a half of a space nut, so I'm going to use a really really interesting story here This is the lunar lander. This is what got Humanity to the moon in 1979 69 thank you. I'm sorry The fascinating thing about this is dependency and reliability was key They had quality assurance programs QA testing Through the wazoo they tested every part over and over again They tested every design over and over again what we talk about when we talk about unit testing these guys were doing 40-50 years ago to a degree way beyond what we are even capable of thinking about But there was a problem because reliability mattered more than anything else This engine on the bottom here Was what's known as a hypergolic engine which meant that it has two valves. Those are the only moving parts You open the valves propellant comes out mixes in the combustion chamber and bursts in the flame and explodes Which means that the engine is Incredibly reliable as long as those valves turn you take off which is great for safety The problem came is that these fuels are incredibly corrosive So what wound up happening is when they built the engine They ran the engine and then they had to completely tear down throw away the old one and build a new one So how would you test something like that? you know you're looking at this engine where Human lives are gonna be at stake every single time it fires and You can't test it because you can't fire it Without rebuilding it Now there's steps that you can take You know we could let's say run water through it put pressurized water in the tanks And make sure everything flows right we could double check the valves we can you know There's steps that we can take and there's tests that we can do without actually testing the system And that's kind of what I want to get across here All your code doesn't need to be a hundred percent unit tested There's gonna be some parts of your code that are gonna be difficult to test the point is you want to take enough Action you want to test it enough to where you're comfortable that it's not gonna break especially the more critical parts It's not gonna always be worth it to refactor, but it's always worth it to be safe so premature optimization and unhealthy focus on performance Imagine if you will you own a my motorcycle shop and I come into your shop, and I say I want you to build me a custom fast motorcycle and You go in your back and say hmm. He wants a fast motorcycle So let me get the most powerful engine I can and stick it on two wheels And you wind up with something that looks like this, which is a Dodge Viper Muscle car engine 500 horsepower Can do somewhere in the neighborhood of seven to eight hundred kilometers per hour in a straight line and Can't turn This is what happens when you think about performance before you think about all of your other Responsibilities and all of your other priorities What about maintainability What about extensibility think about performance when performance matters don't think about performance when other things are a priority Indescriptive naming. I hope this one is obvious. Do I need to really go deeply into this one? I will ask one question though. How many of you would drink this soda and Finally duplication Luckily duplication is one that the programming industry has been harping on For five ten years now with dry. Don't repeat yourself. So be careful when you copy and paste all the things There is one caveat though and this is more of a personal anecdote. I Personally practice what I call the rule of three Which means I will copy and paste something once Because I typically don't know enough About what I'm copy and pasting to actually abstract or refactor or do anything So I'll copy and paste once the second I needed a second time the second I need it in a third place That's when I stop I refactor and I deduplicate It's a trick that I've been trying I've been playing around with for a couple years and it works incredibly well for me Give it a shot So that's stupid Any questions at this point Yay Stupid stupid embodies lessons learned from bad object-oriented code straightforward So it's good object-oriented code gives you a whole bunch of things. It gives you modularity. It gives you extensibility It gives you easy to read and easy to understand code It gives you clean abstractions hopefully But it all comes at a cost where it actually all comes at a lot of costs a lot of times we've heard in procedural programming of this phenomenon called spaghetti code Where the code is so convoluted and the flow is so convoluted that it's hard to keep track of where all the pieces go In object-oriented programming we have a concept very similar called lasagna code It's code that is so layered. It has so many abstractions that it's impossible to understand It tends to be slower at runtime This is not as big of a deal as most people make it out to be because what you lose at runtime you save at developer time Well, why would we want to save developer time? Well, I don't know about here But in the US the developer costs a lot of money and a server costs a little about a little amount of money I'd rather throw 10 servers at a problem than one developer now obviously that depends upon what you're talking about that depends on the project but We're talking trade-offs. We're not talking absolutes and Attends the other really big thing that I think most people when they talk about object-oriented code that they miss is it requires a lot of tacit knowledge and What that means is if you look at a brand new code base that someone else wrote It takes you a long time to spin up and this is very true. Actually, it's incredibly topical at this point with Drupal 8 a Lot of people when they first look at 8 right now today are gonna go, huh? I don't get this this makes absolutely no sense and in fact you're hearing people saying that over and over again You're seeing it on Twitter. You're hearing it at this conference The difference is Once you learn how that code was written once you learn the patterns that it uses Once you learn the conventions and there's a lot of overhead This is not something that you're gonna do in a day or two once you learn the principles All of a sudden everything opens up everything makes sense and the entire system will magically be not simple But relatively easy to understand But that tacit knowledge that knowledge of how things are structured is Often overlooked by people and that is a valid cost of object-oriented programming It's also a cost of all other kinds of programming, but let's leave that aside So let's look at some code. We've come this far talking about cars and random things. Let's actually look at some code Hey, we're looking at a car code Let's imagine for a minute that we're building a computer program That's going to drive a car So you're gonna put this program in control of the steering wheel and the gas pedal and you're gonna make it drive How would you interface with that car? Well, you might do something like this Where you have a turn right method a turn left method a go faster go slower All these different methods that are in the same interface and on the surface. This looks pretty straightforward But let's think about solid. What is the responsibility of this class or of this interface? Well, it's to navigate. It's to accelerate. It's to shift Wait, that's weird and it's to start that that seems like it's trying to do a lot of things and it is Is it open to extension? What if we want to change the transmission? Can we I don't know In fact, if we went through this almost every single one of the solid principles would be violated here So let's try to refactor this. Let's try to make this simpler. In fact, let's split this up into three different interfaces Let's make a steerable interface So we could now plug in a car We could plug in a remote controlled car. We could plug in a boat We could plug in an airplane all we care about is that we can control the direction We can go left or we can go right within some angle of 360 degrees We have an acceleratable interface the car is Accelerable because it can accelerate and it can decelerate and We can shift it the point here is not that we change things around the point is that we simplified our access of it and We're conceptualizing things differently. We're thinking in terms of how will we interact? What's the behavior? We're expecting? Versus what is the system we're expecting? But you know what? Enough with this. Let's actually look at some real real real world code. That's currently in Drupal 7 Mail system interface Anyone here familiar with this? Okay, quite a few Very very very simple interface. It has two methods, right? This should be simple. This should be good code, right? Okay, what's the responsibility of this class? well, it needs to format a message Because we can't format a message until we try to send it so as part of your sending it We're gonna format it and you know replace BB code or markdown with HTML and do all that other fun stuff Then we've got to encode it because emails require that emails are encoded properly Then we have to put headers together because we need to know from into and all of this other stuff Then we need to actually physically send the mail and We also have to set some phpi and I settings This seems weird. This seems like it's trying to do a lot Is it open for extension? What if we wanted to change how it was emailed? Well, we're gonna have to copy and paste That's a problem. That's what we're trying to solve Leaskov substitution principle kind of is okay here I'm sure we could find a problem with it, but you can find a problem with it in any code so But it has one interface and many responsibilities we want narrow not wide and What dependencies does this have? I don't know if you look through it. You can find a bunch, but we're not told anywhere. What's happening? So instead, why don't we split this apart into three separate interfaces a Message formatter Which formats a message its only job is take an email Render it out and format it Then a message encoder Who encodes it to be sent so it makes multi parts it adds your attachments, and it does all that stuff it handles your headers for you And then a transport which actually sends it out So we wind up with a mail system that takes three distinct dependencies your formatter an encoder and a transport and Sends the email now this mail method would be ridiculously simple. It would be three lines of code It would be format message encode message and transport message or send a message Simple and that's what our goal is each one of these steps is very simple But we can exchange out each one as we need to so if we want to instead of sending an email to send mail If we want to send it to a black hole because we're going to test or if we want to send it to a System log because we want to see what's actually being sent or if we want to copy it to a log This gives us the flexibility to swap out the behaviors that we're expecting with the behaviors that we need So the final thing I want to touch on here I'm talking. I've talked a lot today about principles. I've talked a lot about best practice I've talked a lot about The good way versus the bad way There's a final one that I want to touch on though, which is one that I've coined and what I've been preaching for a long time Which is the principle of good enough You don't have to write the best code possible every single time you need to write code that's good enough for your use If you're a hockey fan, not every single goal is going to be a good clean goal But every time that puck crosses the line the objective is met Your code doesn't always have to be crystal clean It needs to deliver business value Don't let better be the enemy of best or be the enemy of good and if it works it works and If we could all be so lucky so, yeah, thank you and Please provide feedback Any questions? Come on. I'm sure yeah Yeah, we had these three interfaces for the mail stuff And then we had the mail system and then the mail system could itself be an Implementing an interface so we would have interfaces on implementation level and another interface that That's That expresses is on the user level and on the level of the system that use it So the system that use that at a different idea of what is one thing then the implementer. Okay, so The way I would say that is very simple The principle is different if you look depending where you look from sure Oh, no, it absolutely is and a lot of this winds up being judgment calls But where I'd say this very specific example here the mail system is your service That's the con for lack of a better word the controller It's very thin all it does is wire its dependencies together in an appropriate order It doesn't really add any business logic. It doesn't really do anything substantive Meaning there should be no reason why you would need to swap it out So I wouldn't create a explicit interface for this. I Would leave it exactly as it is have one implementation and be done with it and This is the only public one that you should ever interact with you You as a developer not working on this particular module this particular Package should never look at the other three classes. You should never have to look at the other three classes You should ask for a service. You should ask give me the mail system and Have the rest of Drupal figure out. Okay. Well, we're configured. We need to use this format or this encoder in this transport Here's your mail system. Go ahead and send mail Obviously there are edge cases where that's not going to happen But we're trying to simplify here. Yeah, I was thinking of an example in core development that I would disagree it with some other people Like the hook menu everyone didn't like it and for me it was like Hook many you define a lot of things like you define a route, but you also define link and you find title and Then the mess happens when you send that to different subsystems and each and these subs are interdependent and that's bad People also said like this having this in one hook is bad and I for me it seems like For the app for the user or for whatever code that uses it There's just one thing that has a route and the title and anything and then for the subsystems It's like different things So it's not evil in itself to just have this stuff all in one hook But just later if you then you have to divide it and then you cannot have these interdependencies that It really depends on what you're looking at and what you're doing as well I mean there's gonna be times where it's gonna make sense to have it all in one hook as you say when there's gonna be times it makes sense to split it out into multiple and Typically when I run into a situation like that and I'm not sure which one is right. I'll typically implement both So I'll have the lower three lower level systems if you need to hook into them and then a higher level of abstraction that you can use Any other questions Come on, there's got to be questions Please no Don't make me beg. I'll beg Okay, we have a question over here and Over there. Okay. There we go How would you do this in Drupal 7? Normally you you have a lot of free functions and a lot of hooks of course an object oriented code It makes a lot of sense that you could do it real pretty but in Drupal 7 how would you do it? Okay, so I'm gonna say something that I have been Both praise for saying and yell that for saying but I'm just gonna say it anyway Drupal 7 is object-oriented Drupal 7 uses functions. It doesn't really use classes anywhere But if you look at the patterns and you look at how Drupal 8 is built and what it's doing It really is object-oriented code. It is what we're talking about here It uses design patterns except it goes through a lot of overhead of Breaking those design patterns down breaking them apart and putting them into functions to try to make it easy So the canonical example. I think of this is the hook system. The hook system is easy, right? It's just an event. Well in object-oriented code We have something called the observer pattern which is literally identical to the hook system You have something called a mediator Which is in this case Drupal's hook system which says I'm going to handle Communication when an event comes in an event comes in okay, we're gonna go through turn it out and then send it out To everybody who's registered to receive it So if you're gonna do this in a Drupal 8 style a Drupal 7 style, and I'm using air quotes What you could do is break this down into three different hook systems Where you have a hook message a hook mail format a hook mail in code and a hook mail transport Or you have a registry a variable set where each one of these is set in a setting So it's really just about controlling the dependencies you can do Polymorphism without objects you can do it with variables and Drupal 7 does a very very good job at that So objects help they help organize, but they're not necessary. I believe you have one over here So about this new Drupal 8 object-oriented structure Where do I find information about it? How do I learn how these different classes are there and to kind of dig into it? Okay First I will put up a disclaimer. I am not a Drupal developer. I Do general PHP work. I was a PHP core developer for a while So I don't I'm not I don't have the authority to ask that to answer that question explicitly, but what I will say is So it's based on symphony symphony components are incredibly well documented and they're incredibly well designed Start playing around with them start getting used to some of the conventions There's a micro framework called Sylex Which lets you use as some symphony components and lets you start playing around with certain of those patterns and certain of The other components and that'll start building the foundation For starting to dig down you start to understand some of the terminology like what is a kernel? You know, it doesn't really make sense until you start to use it once you start to use it It goes light bulb. This is simple. Why weren't we doing this before? Hopefully? Might not have it happen everywhere My questions relate actually to what we just have on the display this one, okay Yeah, and it's about dependency injection. So sometimes as we are separating behaviors into separate interfaces Sometimes you might need to know Explicitly how those are supposed to work together. Yep So would that be a case where you don't do the dependency in that direction via the constructor? But instead have an explicit set us for the dependencies. Okay. We I know that's a huge debate about that, right? How you do it There is a debate I have a very firm stance on this debate Which is if you need the dependency to function in this case you absolutely need there's no sane way of operating without all three of These they belong in the constructor Simple as that simple as that if you can optionally get away without one then yes, you could use a setter But where I will go if you notice the bottom link right here is a you'd link to YouTube I did a video talking about dependency injection. I Do programming videos? I haven't done one in almost a year. I am sorry, but I will do more But where I want to go though is this this class right here is using dependency injection It's not using a container, but it is using dependency injection. Does that How do I know? That's okay So if we look at the interface How do we know that this is using dependency injection and the point being is the interface is right here? This is the interface No, it's you have to look at the class typically the current Try to think the current best practice is to not include constructors in an interface So really you have to look at the class instance that you're instantiating to decide what its dependencies are and that's actually how symphonies dependency injection container and Zen's Zen frameworks dependency injection container work or they can work is that they can reflect on the class Look at the different. Well, okay. You need a message for matter And since I have that over here that you need a message encoder I have that over here, and you need a message transport, and I have no idea how to make that so I'm gonna throw up So, okay Any other questions any other comments cyber marks? No? Oh, thank you. Oh Oh Yeah, we have If I write you mentioned that singleton in most cases is a bad thing According to my experience sometime some things better to express as a singleton I don't know for example like HTTP request Can you please give a bit more extended comment what wrong with singleton if you initiated it properly, okay? Let me take a slightly different example first, and then I'll come back to that one Let's say you use the most common use of a singleton, which is a database connection database colon colon get instance Great, right? So you go along and your entire application is built using this and then all of a sudden you realize well wait a minute I need to refactor so now I have two different database connections one for reading and one for writing and This seems like a really weird thing to do except when we come down to performance sharding and to replication We may actually very well need to do that so that way we can read from different reed slaves and have different rights slaves If your code is written using singletons you have to rewrite your entire application Because you need information that happens before that singleton is called to figure out whether you need a read instance or a write instance a Lot of times you can get by with a singleton a lot of times It will work and it will be clean it'll be easy and it will You know just find out work The problem comes is when it stops working when you have a problem that changes just enough where the singleton becomes a problem You're now stuck with rewriting your application Whereas if you were to use proper dependency injection or promise proper service location or some of the other patterns You at least have a way of handling it without rewriting the whole application. So for the request singleton Sounds great on the top level. We only have one request right we're in PHP What happens when we want to do something like HMVC or hierarchical MVC where we want to have a single page composed under multiple resources Now we can no longer issue a sub request for that Internally because we have this one request so you wind up swapping things out in this really weird confusing tangled mess Rather than just simply passing the information along as it needs to be I Completely get it in that this I think a lot of it gets back to this Which is if you're writing one off code if you're writing code to solve a business problem a singleton may be good enough for you That's fine You know I'm not going to stand here and say never ever under any circumstances write a singleton But it tends to be a bad design because if you let it get out of control It'll hurt you if you need to reuse it. It will hurt you. So good Okay, any final no, okay. Thank you