What is the point of design patterns?
Joel Clermont (00:00):
Welcome to No Compromises, a peek into the mind of two old web devs who have seen some things. This is Joel.
Aaron Saray (00:08):
And this is Aaron. I like to tell this story a lot about when I worked with some RPG programmers who work on the AS400, which is a medium frame computer, a little bit older school. It's a green screen, they call it. You probably use it, you just don't know it.
Joel Clermont (00:30):
All right, Grandpa.
Aaron Saray (00:32):
They're an insurance company, as they're in banks, all these different stuff. I worked at a company that had a number of those programmers and... I mean, there was some challenges between our two worlds communicating. Like, they would print out code and hand it to me. That was weird. But there was also some stuff, I kind of put that stuff to the side and I was able to learn a lot from them because they had been programming a lot longer than I had. One of the things they really kind of hammered into my head was design patterns. I'd even written a book now on PHP design patterns but there's one that pops up a lot that I find pretty interesting that people have opinions on. We're not ones to stray away from having opinions on things so I thought I'd talk a little bit about the Singleton design pattern.
Joel Clermont (01:25):
I want to say I'm excited, but it sounds kind of boring, Aaron. You got to make this interesting. Like, you got it started good with the RPG because I thought, "Oh, role playing games, this is going to be interesting," but nope. All right. I'm expecting a spicy take, some sort of controversial opinion. Let's hear it.
Aaron Saray (01:46):
Well, you're not going to get that. But, no, I'm glad you responded that way because a lot of people their eyes kind of gloss over when you talk about design patterns. They're like, "That's boring." It's like, "Well, is accomplishing the task easily in a correct way, getting money, and seeing your visions come to life boring?"
Joel Clermont (02:06):
No.
Aaron Saray (02:06):
Then maybe you're in the wrong job, you know. But, no, design patterns just for those who aren't familiar is just basically patterns that we've developed in any programming language that kind of are the same going from each one to each one. They're like, "If you have to do this particular set of requirements or task or whatever, here's one way that a lot of people have proven to be good, best practices that is maintainable, that is efficient, that a lot of people understand."
Joel Clermont (02:32):
I like that point. Because sometimes in the Laravel world we think about like, "Oh, what applies to Laravel? What applies to PHP?" But like you just said, this is cross programming languages. These are like general purpose concepts that can be broadly applied.
Aaron Saray (02:49):
Yeah. You want to get better at Laravel? Learn a different language as well. There's all these different cross sections and stuff but... The one I want to pick out, because there's many. I mean, it depends on who you ask. There's many different ones, but Singleton is the interesting one because there seems to be some confusion on how that's used or why you might use it. A quick definition of what Singleton is-
Joel Clermont (03:12):
Please.
Aaron Saray (03:12):
... it's basically the idea that when you make an object from a class, like new AaronService or something like that, that you really only ever have one instance of those ever through the life cycle of this code. There's times when you can use a service or object over and over and over, and then there's make a new version and there's other times when you might just want to keep it just one instance ever. I want to talk a little bit about why you might do that, why you might only want one instance of something. There's a couple reasons. First is actually speed. There's a lot of different things to consider here but one of the things would be, is this working with maybe a third party or does it have to... compile is too strong of a word, but does it have to build something programmatically that takes some time, that can be reused? Does it have to do some sort of handshake with your other code? There's all these different things. Basically there's this concept that it's expensive to make a new instance of this. And if we don't always have to make a new instance of it, why would you?
Joel Clermont (04:23):
No, that makes sense. That's easy even for my small brain to understand so I'm with you so far.
Aaron Saray (04:30):
Then there's also this idea that maybe you make an instance of it and then have to configure it during the instantiation or afterwards, or whatever. Then you want that configuration to be the version of this, the service or object or whatever that you use through the rest of your request lifecycle. So there's also a configuration.
Joel Clermont (04:51):
And the configuration isn't... it's not like a subset of performance where the configuration takes a lot of time, but it's more about like consistency of configuration?
Aaron Saray (05:01):
Yeah.
Joel Clermont (05:01):
Okay.
Aaron Saray (05:01):
For example. Again, this is why I thought this was a little bit more controversial in a way because people will right away maybe disagree with this. But let's just say you have a multi-tenant system. You could determine what tenant this code is working on right now and then add that as context to a service. You don't want to have to determine every single time you need that service what the context is. So you can just determine it once, set it, and then keep it as a single instance, and then you're good to go. The question probably next is like, well, why does this even matter? Why are we talking about this as a sort of process or procedure or design pattern if we can just pass things along through global variables or things like that, right?
Joel Clermont (05:50):
Sure, right.
Aaron Saray (05:51):
Which is not a great idea. We don't want to work with global variables. If you're thinking about it in the context of maybe a newer way of doing things with dependency injection, that's where this becomes really powerful. In Laravel we know that there's a lot of automatic dependency injections through it's magical interpreting the type of parameters and different methods. So this idea of this singleton allows us to configure it maybe once or create it once or whatever. Either when it's first used or even in one of our service providers or something like that, then whenever our dependency injects again, we can get that same instance of it.
Joel Clermont (06:33):
The thing that's using it doesn't even have to be aware that this is a Singleton or not. It's like something that the service container... you configure it there and the framework takes care of it for you at that point.
Aaron Saray (06:46):
Exactly. There is expenses obviously with this too though. When you think about whenever we have something like a Singleton and we create it, that means that chances are we're not doing any garbage collection immediately. We're not unsetting it, we're keeping it available through the lifecycle of our request. Which could be many things and we're not necessarily caring about the memory that it uses. There's other sides to this too, is like you don't want to make everything a Singleton because it makes garbage collection, or... There's just a lot of ceremony in setting one up. You have to make sure that once you have an instance of it, you can't create another instance and things like that. There's been pushback on people using Singletons too because it's like, "Well, then I have to have something built or I have to keep it in memory." Or, "It doesn't feel very compartmentalized." That's why all these different design patterns... we're just talking about one in specific but are taken on a case by case. So, when would you want to use this verses when would you not?
Joel Clermont (07:46):
Just to clarify one thing. Because PHP is maybe a little unique in the way that the code is executed in the context of a request, for example. Let's just talk about web PHP. When we're talking about a Singleton, it's really for the life of a single request, which is a single person or user coming into the system. It's not like for the life, until you reboot your web server or something. It's scoped to the request.
Aaron Saray (08:18):
Right. Well, you could use it in a console command that's always running or-
Joel Clermont (08:22):
Or a job.
Aaron Saray (08:22):
Yeah, a job. But that's still usually one request and then depending on how you have your stuff configured, it'll unset it or not. That's another thing to keep in mind is if you're going to use something, what are all the flashy new tools, Joel, where things are running all the time? I can't think of their names, but-
Joel Clermont (08:40):
Like FrankenPHP or Octane?
Aaron Saray (08:44):
Yeah, those sort of things when you have to make sure that you are very careful with that. But then again there's that benefit of, "Well, we want something speedy, we should only do the slowest most expensive thing the least amount of times that we need to."
Joel Clermont (08:59):
Same principle.
Aaron Saray (09:00):
There's a lot of times when we talk about consistency so we come up with this idea that if you do it this way, you should always do it this way.
Joel Clermont (09:09):
That'd be nice.
Aaron Saray (09:09):
But this is that one sort of thing where it makes a little bit more sense to look at it per instance, no pun intended. Or per context or whatever, and say, "Does it make sense for this to be a Singleton or should it not be?"
Joel Clermont (09:23):
Well, and you can always sound smarter when somebody asks you a question, you can say, "Well, it depends." And then you can show your wisdom and experience. But in this case it truly does depend. You know, one other thing I was thinking of in terms of benefits. So this word singleton encapsulates everything we just explained over the last several minutes. Once you build up a library of these design patterns in your mind, like even within a team, it kind of makes communication shorter, right? Like, you can just say the word singleton without having to explain, "Oh, you know, we should probably optimize the performance by keeping this in memory and blah, blah, blah." It's like it's a shared language that is useful too.
Aaron Saray (10:11):
One of the things I think is kind of weird is that you can fake being asleep but you can't fake being awake.
Joel Clermont (10:19):
First of all, I so much relate to the idea of faking being asleep. Because there are many times where people in my family are asking me to do something, I'm like, you know what, if I just pretend I'm asleep, I don't have to like get up and let the dog out that's barking or investigate that noise in the middle of the night. Anyways, I had never thought-
Aaron Saray (10:40):
Well, that second one was far worse. Like, I get the dog, but I don't have to, "I fake being asleep so I don't investigate that noise in the middle of the night."?
Joel Clermont (10:49):
"It's nothing, it'll be fine," that's my mantra. "It'll be fine."
Aaron Saray (10:54):
"There was some crashing downstairs, but if I pretend I'm asleep my kids or my wife will go and check out."?
Joel Clermont (10:59):
Yeah, if it's that important they'll get out bed and look, right? I'm at peace.
Aaron Saray (11:05):
All right, let me tell you Joel's address here.
Joel Clermont (11:07):
Oh boy.
Aaron Saray (11:07):
Joel said he liked this episode of the podcast a lot because he didn't have to do much. But if you want to see something that Joel does every day...
Joel Clermont (11:20):
Then head over to masteringlaravel.io and sign up for our newsletter full of Laravel tips.