Coding Blocks - Design Anti-Patterns: YoYo, The God Object and More

Episode Date: April 16, 2018

It's time for more design Ant-EYE or Ant-EEE patterns as we venture into cesspool that awaits. Come find out what these patterns are, why you should, and how to avoid them. Bonus: Michael drops the t...erm Heinz Doofenshmirtz - Joe and Allen didn't know this pattern, but maybe you will.

Transcript
Discussion (0)
Starting point is 00:00:00 You're listening to Coding Blocks, episode 79. Subscribe to us and leave us a review on iTunes, Stitcher, and more using your favorite podcast app. And check us out at CodingBlocks.net where you can find show notes, examples, discussion, and more. Send your feedback, questions, and rants to comments at CodingBlocks. Follow us on Twitter at CodingBlocks or head to www.CodingBlocks.net and find all our social links there at the top of the page. And with that, I'm Alan Underwood. I'm Joe Zach. And I'm Michael Outlaw.
Starting point is 00:00:30 This episode is sponsored by Airbrake.io. When your website experiences an error, Airbrake alerts you in real time and gives you all the details you need to fix the bug fast. Now, one thing I really like about airbrake.io is that all of their libraries are open source. You can go to their GitHub page and actually see the code that you use to integrate with their product. And the best part, they nailed the most important thing. The readme in these repos is phenomenal. And you can tell that they really are just a dev-focused company. Right now, CodingBlocklocks listeners can try Airbrake free for 30 days, plus get 50% off your first three months on the startup plan.
Starting point is 00:01:14 To get started, visit airbrake.io slash codingblocks. That's airbrake.io slash codingbox to start your trial today. All right. So first up, a little bit of news. I want to say a big thank you for those reviews. You know we love them. From iTunes this time, we got MikeRG87 RM Quist, Both Zoli, even Michael can say this one. I think I got it.
Starting point is 00:01:58 And Benny. And thank you guys for leaving those reviews. I love that. And we've got some big news for us here. and thank you guys for leaving those reviews. Oh, and we've got some big news for us here. We've been trying to get on Spotify for a long time and we're finally there. So if you like listening to episodes on a podcast on Spotify, then you should check it out because now we can find us there. And I don't know,
Starting point is 00:02:20 can you speed up podcasts in Spotify? I don't know, but that's a super important question that I'm going to find the answer to right now. Well, while he's doing that, I feel like the way you're saying that, though, is like, we finally made it. We're on Spotify. We're five percenters. Yeah. Yeah. Yeah.
Starting point is 00:02:40 All right. Hold on. Podcast speed. Boom. You've got one, 1.2, 1.5, 2X, and 3X if you're insane. Whoa, I'm switching to Spotify. Yep, 3X. Well, good to know.
Starting point is 00:02:53 So yeah, if you listen to podcasts there, you should check it out. Excellent. You can listen to all my podcasts now in five minutes. And we do have a link at the top of our page that's got the little Spotify logo. So if you want to get there quickly without having to search for it, just come to our site, hit the button, and it will open up in your Spotify app. Yeah, and I love those little buttons. So if you know of some other great aggregators out there that we're not aware of that maybe we should add to it, let us know. And we've got some pretty exciting news.
Starting point is 00:03:26 So I met John Calloway recently at the Microsoft Summit thing, and he just released a book, which is called The Practical Test-Driven Development Using C Sharp 7. And he gave us several copies of this to give away. So if you would like to get your very own copy of this book, which, by the way, is 50 bucks on Amazon, which are most technical manuals. If you'd like to get your hands on this and be able to learn how to do some practical test driven development, leave a comment on this particular show, which is going to be coding blocks.net slash episode 79. And be sure to go to our site and sign up for our newsletter because we're going to be giving away some of these on that as well. So a couple of different ways that you can win these. So, um, yeah, really excited. So, uh, by
Starting point is 00:04:19 the way, uh, John Calloway and Clayton Hunt are the two guys that authored this. And if you've not heard of the Six Figure Developer Podcast, go check them out. That's what these guys are. They're both co-hosts on that show and highly recommend it. They do similar to us with roundtable type talks, and they will also occasionally have somebody that they interview. And I've listened to several of their episodes and really enjoy it. So definitely go check it out. Yeah. Again, that's the practical test-driven development using C sharp seven. And if I recall, we were going to do one giveaway
Starting point is 00:04:54 for commenting, right? Yep. Am I putting you on the spot? One giveaway. So the point I'm trying to make here is you have a better chance. Well, your odds are going to be probably better if you go through the mailing list, definitely leave a comment. I'm not suggesting that you don't, but most of the ones that we're going to do are going to be through the mailing list. Yep, definitely. Oh. And also, by the way, I think this is worth pointing out. So if you're watching the video, you'll see they've got, um, a bookmark as well as a business card. And they even have a sweet little sticker as well for those of you that like sticker swag. That's everyone. Yeah.
Starting point is 00:05:29 That's all of us. That's some people. So, yeah, definitely check it out. And a big thank you to John for sending those over for us. Absolutely. And now let's go ahead and dive into the topic. This time we're finishing up with that, talking about object-oriented anti-patterns, which are're on now. The God object. Anti-pattern. Anti or anti?
Starting point is 00:06:10 Oh, I thought you said object pattern. Never mind. Sorry. That was my mistake. But is it anti or is it anti? I think this is important to get out of the way right now. On three, we all say what we think it is. One, two, three. Anti.
Starting point is 00:06:24 You said anti, didn't you, Joe? I did. I said anti. All right. So we've resolved nothing. All right, here we go. As usual. I'm pretty sure if you were to rewind back
Starting point is 00:06:39 and listen to my first pronunciation, you would have your choice, right? You said anti. That's not correct. All right. Sorry. What's the first one? Right.
Starting point is 00:06:50 So the God object. Here we go. So this one you've probably seen. It's concentrating too many functions in a single part of the design. And that is, you know, it typically knows everything about what's happening in the application. It knows how to interact with all of it, right? Like this thing knows everything, which can get ugly, right? Because as things change further down, then that thing has to change to know about those things further down. It's overly complicated because it knows about maintains the state of most of the application
Starting point is 00:07:27 right which is going to be nasty and it becomes a mediator for everything that's going on now the interesting thing is at least from the wikipedia thing it says the patterns used in micro controllers were centralized control is more important than the elegance and the ease of maintainability which which makes sense. But yeah, for the most part, if you have one thing kind of pulling the strings for everything down in the code, that's the God object, and that is considered an anti-pattern. You know what this reminds me of is some of my early days, like my main function, right? Like that main function would just be awful.
Starting point is 00:08:08 It was probably just way too many lines of code. It did way too much. It knew too much. It was setting up way too much state, passing too much state, retrieving too much state. That's what this kind of reminds me of. But man, you didn't have to open like 30 files. That's kind of nice, right? That is nice.
Starting point is 00:08:23 That's important. Yeah, you just had to scroll 3,000 lines. Right. Yeah of nice, right? That is nice. That's important. Uh, you just had to scroll 3000 lines, right? Yeah. Regions, man, regions.
Starting point is 00:08:29 Oh, right. God regions are an anti-pattern. Uh, so I wanted to say, um, I'm not bad about the God objects, at least nonsense,
Starting point is 00:08:37 like kind of like getting out of like, you know, basically first learning, first learning how to code, but I'm really bad about Demigod objects where i've got like seven objects that are somehow involved in like every process in my little app and they're not all created equally right so you've got like you know one that's like easily better than a bigger than three of the others combined right so it's kind of like the the greek pantheon there like
Starting point is 00:09:01 there's some gods that are just better than others. That's awesome. You know what's funny about this, though? Going back to the Clean Architecture series, if you remember right, when we got into the part where they talked about you set up most of your dependencies in main, right? That, granted, it's not the same thing. You're not maintaining state. You're not keeping track of everything in the application. But it does basically mean that you're going to have a pretty gargantuan at least entry point into your application, right? It's not the same thing, but it was kind of funny that it's sort of in the same vein.
Starting point is 00:09:39 Yep. So that's it for mine. But why is that a bad thing, though? Do we say, like, who cares? What, having the got object? Yep. I mean, really, the bad thing is it's almost impossible to maintain, right? Like, if it's managing all the state for your entire application and it has to know about all the inner workings of all the classes in there, this is just going to be a mess, right?
Starting point is 00:10:00 Like, if you ever need to change anything, good luck. Yeah, I kind of think it's the opposite of the single responsibility pattern where a class should only have one reason to change. And the deal there is that if you got all this stuff just in one big file, sure, it may save you on total lines of code. But every time you change that code for any reason, then you're changing all of the code for your application. So it makes everything highly volatile. Yeah, I feel like there's going to be some overlap between some of these because one thing I was thinking about is that if there's any kind of public interface to this thing, then it's going to be more difficult to change that later on.
Starting point is 00:10:40 If you decide to refactor that and be like, okay, I'm going to break this God object part, but if that interface is already public, that's going to be difficult. Well, what if you've got a facade? You've got one object that represents several others in order to make it easy to call. So if you've got some sort of library or something that does some stuff and you've got a NuGet package or whatever, a Java package, you may want to only have one kind of object that exposes everything. So it's just easy to use. Like, I don't want people to have to, you know, look at 10 different pages in the docs just to figure out how to make a simple call. But that wouldn't be a God object at that point, right? Like that's just facilitating the, the ability to use those other things. It's not maintaining
Starting point is 00:11:21 the state of, of an application, right? Like it's not trying to control everything that's going on. It's literally just a, oh, you wanted to do, you want this, I'm going to route you over to this method, right? Yep. Okay. I'm happy with that. So moving on to the next one, which is an object cesspool. Hey, one other thing, I'm sorry. I just wanted to go back to that last one. It was that one thought that I was thinking of was that inheritance or composition over inheritance. So just because, you know, that God object, as you were describing it with the facade, you could still have your one object that you're exposing out publicly as part of your NuGet package or NPM module or whatever. But if you're using composition to tie those pieces of functionality together,
Starting point is 00:12:11 then it might not necessarily still count as a God object though. Right? Am I wrong? No, I'd say you're probably okay with that. Like, uh, it's just kind of masking and bringing all that stuff together and kind of one point. So I'd say it's probably got like a kind of a wide exposure, like it's probably very likely to break if you change anything underneath. But I don't think it would count as a God object because it just doesn't. Well, yeah, because that functionality wouldn't be necessarily in line. Right. It's not all in that one class.
Starting point is 00:12:41 You're using the other classes. Right. Yeah. So it's about the logic really being consolidated in one spot. Correct. I'm definitely thinking of languages like, not like a Java or a C Sharp necessarily, where you would use interfaces to introduce your composition, but languages where you can introduce mixins.
Starting point is 00:13:02 JavaScript, for example, where you could like do a mixin to apply, you know, functionality from one place into another, you know, and it is bringing that functionality along with it. So like the definition of if you needed to change that for any reason, you're only changing it in that one place. Does that make sense? Yep, it does. And the mixin is still doing the work. It's not your main object that's knowing about how to do all the work. And I think that's where the difference of the the God object versus not comes in. So the mixin would act like your your interface and C sharp or something. Right. So yeah. All right. So object cesspool. Yeah, object cesspool. And I
Starting point is 00:13:43 really like this definition. But first I wanted to kind of talk a little bit by what we mean by a pool here and what a good pool would look like. And a pool really can represent any sort of collection of objects that you would kind of pull from. That's funny, different words that sound the same. So let me use a different word
Starting point is 00:14:00 that you would grab an item from this pool, use it, do some things, and then put it back in the pool so that something else can grab it. An example here might be like database connections. You have a pool of, say, 20 of them because they're expensive to create, and you would just keep them around. And you've got a web app or something, it'll grab database connection as needed. And if it goes to grab and it can't, it'll kind of get queued up or it'll wait or do something rather than create a new one because it's expensive either in resources or time. So a good healthy pool is going to have objects. And when you can grab them, you can just use them
Starting point is 00:14:32 and drop them, forget them, and don't worry about it. Now it becomes a cesspool when you're not resetting those objects back to a good state. And like we said with the database connection here, the idea is that these things stick around for a long time and you're not doing them up over and over and over again. They are long-lived objects possibly living for the lifetime of your application. So that means if you're setting state in there, like say a command timeout on a connection string, then if you don't reset that when it gets added back to the pool the next piece of code that comes along and requests it and gets that item might still have some of that dirty or stale state so the idea here is that the cesspool are objects whose state have been tampered with and haven't
Starting point is 00:15:18 been reset properly you guys ever seen anything like that in in the code you've dealt with oh definitely yeah i'm trying to think like um most of the kind of the pools that i've used have been properly. You guys ever seen anything like that in the code you've dealt with? Oh, definitely. Yeah, I'm trying to think like most of the kind of the pools that I've used have been built into the library. And it's been something like connection string library or some other, yeah, like a thread pool. And in those cases, like the, like, I don't even really think about it. I just kind of assume that like, you know, the.NET runtime or whoever knows how to clean that stuff up. And I've never really thought about it before. Yeah. I mean, usually it is completely managed, right?
Starting point is 00:15:49 Like the whole way the connection pulling would happen is they have to match. The signatures have to be exactly the same. So you couldn't go change it. But yeah, I've definitely seen things to where, I don't know, like a locking thing or something from a queue that you can push or, you know, grab off a queue or whatever and something changes in it. And all of a sudden your thing doesn't behave the way you expect it to because something wasn't the way that you expected it to be. Some sort of starting state, right? Yeah.
Starting point is 00:16:18 One thing I kind of thought about here with JavaScript is, you know, JavaScript, it's got this notion of hoisting variables. So it doesn't really matter where you put that var. It ends up kind of getting moved by the interpreter. It gets moved up to the top of that function. So I thought like maybe if you didn't realize that things were getting hoisted, it's possible for you to get in a bad state here, depending on how you're kind of using that variable, like say in a loop or something. I think in most cases, you're probably still saying that var something equal to an object or an array or something. So you're probably okay.
Starting point is 00:16:49 You're probably gonna be wiping out that memory anyway. I thought that might be an interesting case in JavaScript where it's really easy to not realize that you're not initializing some sort of locally scoped variable. You're reusing something, whether you realize it or not. And so I thought that might be one easy way
Starting point is 00:17:04 to kind of get into this mess. But I have never seen that in practice. And I think that the way I tend to write code avoids that completely because I tend to not mutate things like arguments that I pull. In fact, I almost never do unless it's the extreme circumstances because I'm always trying to avoid doing things like changing state unexpectedly for my callers or colleagues. Well, I will say one thing that you just mentioned was in JavaScript, the varring of variables, right? If you were using the latest ECMAScript type stuff, you want to use let as much
Starting point is 00:17:37 as possible because then you can avoid any of those kind of scoping issues that you might run into, just as a side note. But yeah, it is a good point. Like in JavaScript, you could literally just grab a variable that you didn't realize was global scoped, right? And all of a sudden you're touching it and changing it and you have no idea, right? It's not like you got a warning. But I mean, global scope, that's a different problem than cesspool though, right? I mean, yeah, I'm still having trouble trying to wrap my head around like a real world use case of the cesspool i think the database connection it could be an example if it was done
Starting point is 00:18:12 improperly where uh let's say it didn't reset it back to zero so it like whenever the connection got disposed of or it got sent back to the pool it didn't go and reinitialize all of its variables back to the default state but i feel like and reinitialize all of its variables back to the default state. But I feel like that's not a real world example though, because the connection pools do all of that stuff for, I mean, there are specifically the thread pools are specifically designed for that. The connection pools are specifically designed for that. I'm thinking of like, like what? Well, the connection could be right. If you're leveraging, like, for instance, if we're talking about SQL server or some sort of JDBC data source, if you're leveraging the connection pooling that's done by editing the connection string, then that's true, right? That's set up several connections and you just let different objects use those connections wherever they want. One of the things that he put in here
Starting point is 00:19:09 is, you know, one of these things needs a super long timeout because it knows that this query can run for five minutes, right? And that thing doesn't get reset before you put it back in to where other people can grab it. Then all of a sudden what should have been a 30 second timeout on some page ends up being five minutes, right? Yeah, again, I just, I mean, man, if you're writing your own connection poll, we need to have a talk. Yeah, I mean, it could be done. Granted, there's a lot of things there that you should leverage. But yeah, I mean, I think it's just the notion of it though. You know, the whole idea that you're changing the state of something that everything else
Starting point is 00:19:50 expects to be in a particular state when it goes to use it. See, I'm almost afraid. I'm almost afraid to take this conversation to a place that I really don't want to take it to because it's, it's, Oh man, it's going to eat up my soul. It to hit, to bring this up. But I kind of feel like, I kind of feel like this is going to be a stab at my boy here. Singleton. It's going to bring a tear to my eye to say it.
Starting point is 00:20:10 Because I feel like that's where somebody's going to bring it up, right? That it's not – its contract does not conform for reuse, right? And if you're changing the state of it right it's not resetting itself is that like and maybe that's where you know someone might make the argument they're like why they think that the singleton is an anti-pattern but i don't think that that's a cesspool though because well it's not a pool but, but even then, you can set up the singleton to where you can't modify the state, too, right? So that's not necessarily… You could, sure.
Starting point is 00:20:53 So, I mean, I think it's just a whole convention, right? Like, I don't think it's something that we're going to be seeing a whole lot, but… Well, I got an example, I think, that we've all seen before. So you're working on some sort of web app. I'm just going to use WordPress as an example, I think that we've all seen before. So you're working on some sort of web app. I'm just going to use WordPress as an example, right? Where you've got a list of blog posts and you go and you say quick edit and it pops up a modal and it's got like the title box and a description box and a couple other, you know, just input fields, text areas, things like that, check boxes that you can set. And so, you know, you do that, you hit save, you go to the next one, or maybe you even do new,
Starting point is 00:21:26 and it pops up that same modal. And in there, if you're using one modal that's maybe hidden on screen, and then you click new and it just kind of shows it and arranges it on screen to be in the center, then a lot of times it's common to have a reset method because you're not newing that thing up all the time. And what happens is when you first build it, everything works fine. And then at some point, someone comes in and they add a few fields to this thing, a few text areas, and they don't realize that there's this reset method. So it works great when they test their one thing. And then as soon as it gets out into production, someone edits an item,
Starting point is 00:21:58 the model comes up, all their information is good. They make a few changes, they hit save. Then they do new, the form pops up, and those new fields still have the data in them from the edit. Have you ever seen that? Yes. Okay. I like that example. There's not necessarily a pool here.
Starting point is 00:22:15 It's kind of a pool of one. So it's kind of weird. But I think it's the same kind of idea where we've got some sort of data that isn't being reinitialized properly. Yeah. some sort of data that isn't being reinitialized properly. Yeah, that makes a lot of sense because I was actually thinking about something similar where you have pop-up windows that get reused and they don't get reset back
Starting point is 00:22:34 to a good state. And you reuse it so that you don't have a bunch of extra calls and whatnot. Right. And you know, one area I end up seeing a lot of pooling is that with Unity I'm kind of messing around. Like, so if I've got a little game and it's got tiles and you can walk around the
Starting point is 00:22:47 tiles, like it'll only keep like so many tiles as it needs to draw on screen. So like say a hundred tiles, if you scroll down, you know, and keep walking around this big castle or whatever, you're not creating thousands of tiles. You're creating the same,
Starting point is 00:22:59 or you've got the same a hundred tiles and you just swap out like the images. Right. But you can imagine like, you know, if you kind of move to the left or to the right and you just swap out like the images right but you can imagine like you know if you kind of move to the left to the right and you you're setting the properties like can walk through or you know is poison trap or something and you're not resetting that on every time that the tile changes it's kind of graphic then you're going to have a bug where like something looks like grass but you can't walk through it because you didn't properly reset that item when you swapped out its data. You didn't swap out
Starting point is 00:23:25 enough. Cool. So I just thought it was kind of interesting. They say it can happen a lot with multithreading. I kind of feel like a lot of this stuff, like the antepyramids we've talked about, they kind of happen in older languages, more like a C or C++, where
Starting point is 00:23:41 you're kind of twiddling things without some of the compiler checks that things like a Java or C Sharp is going to give you. That makes sense. Is that true? Or maybe even a dynamic language like a Python or something where you don't have like strict checked interfaces between things. I could see that. I mean, your next point that you had here about multi-threaded environments, right?
Starting point is 00:24:10 Like, I could see where that would be an issue if you don't have good ways to access the variables or whatever that's going on in those environments, right? Like, some thread changes the state of something, and then the next thread picks it up while it's sort of in an in-between state that wasn't locked properly or whatever yep and uh what question i hear is how do you know when you're doing this and i kind of think like anytime that you're building some sort of flyway or that you're using some sort of pool and you're doing it it's not built into your library then i think this is something you need to watch out for and i'll typically see like i've created a reset method, but as for getting people to actually like make sure that any code they update
Starting point is 00:24:50 is in there. I don't know about that. They're kind of putting a note at the top. This is like, if you change anything here, make sure to scroll down and add it in the reset. And I know how we all feel about comments, but I don't really know how to prevent that here.
Starting point is 00:25:06 Like this is a case where you've got a reset that needs to be able to reset things back to a good state. Maybe you've got some sort of initialized function that kind of doubles as a reset. And so that kind of automatically runs. And so it makes things only happen in one spot. That's just one idea. So anyway, that's the object cesspool. Things getting dirty, not getting reset properly.
Starting point is 00:25:30 Alright. Well, speaking of dirty, let's talk about everyone's favorite anti-pattern. It's the object orgy. This is, aside from humorous, this is when your object is fails to properly encapsulate uh let me restate this you're failing to properly properly and this is easy for me
Starting point is 00:25:58 failing to properly encapsulate objects permitting unrestricted access to their internals, right? So this means that if you're, if other objects are able to reach into parts of your object that they really shouldn't be able to do, that's this anti-pattern, right? You're, you're not, you're keeping everything, you're keeping more things publicly available or friendly when you shouldn't, right? So the worst consequence of this is that it becomes difficult to maintain and change this object. And this is where I was saying, like going back to the God object, Alan, that there was going to be a lot of – it felt like there was going to be a lot of, how did I phrase it earlier? Like overlap between these. Because it seems like these are kind of similar, right? But maybe coming at it from the other direction, right?
Starting point is 00:26:55 Like the object orgy anti-pattern is the other direction of the god object, right? It's not the god object itself. It's just letting something like a god object control it, right? It's not the god object itself, it's just letting something like a god object control it, right? Does that make sense? And so, yeah, so it's going to be difficult to maintain and change this thing, and this is where I was talking about with the, if that thing is already adhering to an interface and that interface is publicly available, that just makes it that much more difficult to change, right? internal members public that really don't have any reason to be public or providing public getter setter methods for your properties that you really, maybe you don't need a public setter, only you keep that private and just let things retrieve the read-only value, treat
Starting point is 00:28:01 it as a read-only property and only have a public editor. For example, maybe that's what's necessary, but you for whatever reason left it as public. So then it's like, well, how do we get in this situation? Laziness could definitely be a big part of it. This could just be a symptom of coding to an immature design. So, uh, you're still trying to figure out what's needed and you're like, okay, I'll just, I'll just leave this as public.
Starting point is 00:28:36 I might come back and, and, you know, um, I might need this in another module. So I don't know yet. And I just leave it as public. And then either haste or laziness, you just never go back and refactor that to change that. And you leave it there. Or you're just reluctant to change it for whatever reason. You just leave it as public. And then it becomes a problem because now someone else comes along. And they're like, oh, hey, you created this cool object.
Starting point is 00:29:04 And they see these publicly available features. So this begs the question, okay, well, how can we fix this, right? So first you got to recognize the first part of solving any problem is to recognize that you have a problem, right? So you got to recognize the problem and have the willingness to refactor that, right? So going back to when I said that you had the reluctance to change it, well, we're going to have to overcome that and redo it or make this change. And like I said, if these things are publicly available, then that's where it's really going to be complicated. So if you can recognize these problems sooner rather than later, then it's to your advantage to lock that stuff down as soon as possible. And the, like, I was kind of thinking of examples where like, if you were making publicly available APIs, right? You know, you don't want to, you want to keep those things as
Starting point is 00:29:57 locked down as possible before you release it. So once you release it, it's going to be really difficult to change it because you might upset your users because they were taking advantage of things. So I think another way though, that you could probably solve this too, that I was thinking about like on the fly, I didn't, I forgot to write this in the show notes though, was maybe favoring keeping as much of your members private until you know that you need to make them available to the public. And I think actually we may have even covered something similar to that in a, um, part of the clean code series,
Starting point is 00:30:30 if I recall, but I don't remember what that principle would have been called. No, open for close, open, open for modification, close, open,
Starting point is 00:30:38 close principle. Yes. Yes. Closed for modification. Open for, open for extension, close for modification. Yeahosed for modification. Open for extension. Closed for modification. Yeah.
Starting point is 00:30:49 Go ahead. I was going to say like one kind of way to recognize this maybe is if you see a class that has a bunch of like data members mixed with a bunch of behaviors. Yes. Because then you know that like, well, I can set these three things, call a method, you know, reset these three things. And there's just like back and forth interaction. It's not one way. It's this tight coupling between two things that very much know not just about the behaviors, but also about the internal things that those behaviors affect, which means that not only do I know what your methods are, but I know how those methods are operating and I'm manipulating your data to get the specific things I want out of it. So like these might as well be one class at this point, because it's just, it's misleading when anyone looks at anyone individually, because they don't realize
Starting point is 00:31:33 that these things are totally tightly bound together. Yeah. What you were saying is exactly what I was thinking is if you see a bunch of, you know, public properties on a class or public variables on a class, but then a ton of things that say, Hey properties on a class or public variables on a class, but then a ton of things that say, hey, do this or update this or whatever, then you're mixing them up. But then that brings me to this question here, Joe. And this is one of those things that I've seen. And I'm always like, on one hand, the memory footprint comes into mind. But on the other hand, it's like, well, consistency matters. So let's say that you have a class that has a bunch of behaviors on it.
Starting point is 00:32:11 And let's say at the time that you get this class, it also has all the public data pieces publicly exposed as well, right? So maybe it's something like you have your color class stuff, right, that you do a color mine. And so you might have an RGB value, right? Let's say that you want to set the color to fuchsia. If you do that and you may have a method that says that takes in a name and then you can convert that to an RGB value, right? Should that R, should that G, and should that B be public? Or should it be an object that you can only get back because you called the set fuchsia, you set the color to fuchsia, and now you can only get back an object that has the RGB value pair or tuple or whatever you want to call it.
Starting point is 00:33:04 So your thoughts. Yeah, that's a great example. Like you say, you know, basically like, hey, new color, pass the string fuchsia. Then you say, print out my RGB and it's going to be like FFGGAA. Then you say, hey, color dot, you know, R equals AA. Now that color is not fuchsia anymore. So two lines above, you said, Hey, new color fuchsia. But now if I say, is this color equal fuchsia? The answer is no. Like, well, well, what the heck?
Starting point is 00:33:30 Obviously we know that we, we changed it, but I think that's a confusing and that's a really good example of something where we're messing around with the internals of something. Yeah. So that the, the key part I, you know, for anybody that's listening, this whole object orgy is, you know, if something we're going to use that color object, you know, it might go and set the color to fuchsia. But then it might just try and go and reach in and grab the variable for the red that it knew existed, right? That's not how it should be. Basically, when you say set that thing to future, you should get back an RGP or or maybe there's another method you call to get back that RGP, that RGB object that then they could use. They shouldn't be reaching in and touching the storage because that means they know too much about how this thing works. They should have to call methods to get back out what they want to use or call methods to set things that they want to do. Yeah. So in that example, what I want to see is you create a new color past the string. Great.
Starting point is 00:34:30 You can get the RGB back fantastically. I like that, but I shouldn't be able to set those RGB because that's when things get funky, right? If I want, like it's a valid use case to say, Hey, give me fuchsia and now tweak it a little bit. You know, maybe you're doing a gradient or something. And so you want to keep reducing that R by 10 to get you know a nice kind of you know design thing going but uh what you could do is by making those um unsettable then you can basically say hey color one equals fuchsia color two equals you know fuchsia or color two equals color one minus a little bit of red color three equals, you know, and so on. And so these things are immutable.
Starting point is 00:35:07 Yep. Cool. Anything else? No, I was trying to think of another, another example to go along with this. That would be like, but the examples that I was coming up with weren't as good as your color
Starting point is 00:35:21 example, but I was kind of thinking like, maybe if you had some, some object that needed to, uh, you know, for whatever reason you had a, a loop that it looped somewhere in some method, but you had the iterator for that loop as you remember to the class, right. And yet you made that thing public, right? I mean, how many times have we done a 4i equals 0, i less than something, i plus plus type of declaration? What if i was a public member of your class? That would be super disgusting, but a great example of this anti-pattern. It shouldn't be publicly available, but yet it is.
Starting point is 00:36:04 And if anything is using it, well, now you're tied to it. And they could go in and do whatever they wanted and somehow mess with what your internals should have been doing. Right. Yep. Yeah, like one example I'm thinking of there is like imagine you've got a class that represents a row and a grid. And based on its row ID, if it's even or odd, it'll be gray or white. Well, then, you know, a PM comes to you and says, we want this grid to be all gray. We don't want alternating. So you say, okay, well, in this loop, then what I'll do is just set the row ID equal to two.
Starting point is 00:36:37 And that way it's always the color that I want. So that would be an example where we've got some inappropriate knowledge here because your class that's setting that to knows how this behaves on the inside. And it's relying on this kind of what's essentially a private behavior. It's stuff that you're not supposed to know about in order to get the desired effect. So it's being clever. As we all know, like clever code, it's not so clever. Right. Cool.
Starting point is 00:37:03 I like that. All right. You Cool. I like that. All right. You know what I like? I really like reviews. We've gotten so many really great ones and we really appreciate it. And if you would like to hook us up with a review, if you go to the website, coding blocks.net slash review,
Starting point is 00:37:19 we've made it really easy for you. You don't have to install iTunes or anything. There's plenty of places to leave reviews now. And some of them it really easy for you. You don't have to install iTunes or anything. There's plenty of places to leave reviews now. And some of them are really easy. So if you like the show and you want to help us out, just go to codingblocks.net slash review and help us out. And with that, it's time for my favorite portion of the show. Survey says.
Starting point is 00:37:43 All right. So last episode, episode we ask do you why can't I talk tonight do the mouth exercises oh that's that's what I forgot to do to start right because I pretty much didn't want that in the video
Starting point is 00:38:00 of you guys doing exactly what you're doing now so which is a great reminder if you're not you know doing exactly what you're doing now. So, which is a great reminder. If you're not watching the videos, uh, you can, um, you can go to coding box.net slash YouTube. And,
Starting point is 00:38:12 uh, you can see this in all of its digital glory. Um, last episode, we asked, do you participate in open source projects? And your choices are yes, but only on my own projects. Yes, but only when I'm trying to beef up the resume.
Starting point is 00:38:34 Yes, but it's documentation, not code. Yes, but I only participate in projects owned by others. Yes, I have some of my own projects and I participate in projects owned by others. Yes, I have some of my own projects and I participate in projects owned by others. And lastly, man, I'd love to, but dang, who has the time? All right, let's let Joe go first. What do you think is the most popular answer from our survey, our respondents? I'm going to go out on a limb here and say the real answer is I'd love to, but who has the time? that the people who really felt that way felt that that was not an acceptable answer because they feel a lot of peer pressure or a lot of industry pressure to do this stuff. So I think they would have skipped this survey and just felt bad about themselves like I do often.
Starting point is 00:39:35 And so I think that the people who came and answered this, they're going to say yes, but only my projects at 27%. Wait, you said 20 or 27. I'm sorry. 27%. 27%. Yes, but only on my own projects at 27%. Man, I swear that's almost the exact same logic I was going to use for this. And that's really frustrating. So instead of copying you. Well, you can price his writing.
Starting point is 00:40:00 Yeah, but I don't want to be a complete copycat here. So I'm going to say that these people are just going to go ahead and feel bad about themselves and they're going to answer the survey and they're going to say, man, I'd love to, but dang, who has the time? And I'm going to go with 27%. All right. Yes, but only on my own projects at 27% versus a man. I'd love to, but dang, who has the time at 27% and Alan wins it. Ding,
Starting point is 00:40:31 ding, ding, ding, ding. I love honesty. Yeah, it was probably way higher, wasn't it?
Starting point is 00:40:37 Oh man, it made me feel so good. It was like 80%. Oh God, my people are speaking to me. It was 60% of the vote was man, I'd love to, but dang, who has the time? Yeah, the only reason that wasn't higher is because the people that really are that way, I don't have time to click on this survey and click this thing.
Starting point is 00:40:59 Yeah, I wonder how many people were probably, as you guys pointed out, were probably like, oh, man, I don't want to feel bad about it. No. Well, this is really amazing to me to hear that number. Because you think the audience, the people listening to this show right now, these are the go-getters. These are the people listening to a podcast on their own time while they're driving to work or while they're walking the dog. When other people are enjoying their lives or listening to comedy or, you know... Hold on, let's back up.
Starting point is 00:41:27 This is enjoying your life. I think what he's trying to say, though, is our listeners are awesome. They're just awesome go-getter people that care enough to listen to this in their spare time to try to better them. They're trying to get better at their craft. And even smaller on that funnel are the people who
Starting point is 00:41:44 actually come to the site and participate in the survey. So like a small percentage come and do that. And out of that small, small percentage of a percentage, 60% of them said, I'd love to, but dang, who has the time? I mean, I get it. It's hard. Like there's no question about it. So yeah, that's not it. What was number two?
Starting point is 00:42:03 Was it the first one? Yes, but only my own projects. Uh, do you, do you want to gamify that answer too? Or do you want to Joe? I kind of just want to know. Oh, okay. Yeah. It was, uh, surprisingly, yes, I have some of my own projects and I also participate in projects owned by others. 20, 20%. Don't get it. No, it was closer to 14%. Okay. Yeah. So, I mean, of my own projects, and I also participate in projects owned by others. Wow, 20%? Go get it. No, it was closer to 14%.
Starting point is 00:42:27 Okay. Yeah, so, I mean, there was a significant drop. I mean, like I said, the other one took 60% of the vote, so everything else is going to be a significant drop. But, yeah, that was interesting. Yeah, we should have had an option on there that said, like, yes, five years ago on my own, and once once a year at Hacktoberfest I get my one commit in so I get the shirt. Yes, prior to kids. No, now that I have kids. Right.
Starting point is 00:42:53 Now that I have responsibilities, nothing. Right. When I was 23. Yeah. Or I guess your own projects could count as any presentation I give. All right. All right. Well, do you want to read this one, Joe, or do you want me to?
Starting point is 00:43:14 Sure, I could do it. Okay. We love these surveys, by the way. We always get so much out of it, and it's always surprising to me. So thank you. And today's survey, we're asking an interesting question that we've been talking about a little bit recently. And we want to know how important is Docker? And one option is that it's very important. Docker is the new git and that
Starting point is 00:43:36 someday we're all going to be expected to know it. The second is, eh, containers are awesome, but Docker itself, not so cool. Third, nah, this is just a stepping stone to something much bigger and better. Or fourth option, nope, I build and deploy from my laptop. I think we forgot an answer here. It should be like, nope, we build and deploy from Jerry's laptop. Or that computer underneath Charles' desk, don't kick the power out from underneath that thing.
Starting point is 00:44:09 That is our build server. You push the power button on what? Yeah. We don't have a backup on that thing. Oh, man. So, yeah, go to the site. This is going to be codingbox.net slash episode 79, and you'll find that survey
Starting point is 00:44:25 right there and let us know how you think how important Docker is. This episode is sponsored by Airbrake.io When your website experiences an error, Airbrake alerts you in real time and gives you all the details you need to fix the bug fast.
Starting point is 00:44:42 And by all the details, we really mean all the details. If you hook up the NuGet package for an ASP website, then you're going to be logging info specific to.NET. And if you hook up the WordPress plugin, for example, then you get information that is specific to WordPress and PHP. On top of all that, it's really easy to pass your own custom data as well. Right now, CodingBlocks listeners can try Airbrake free for 30 days, plus get 50% off the first three months of the startup plan. To get started, visit airbrake.io slash CodingBlocks. That's airbrake.io slash CodingBlocks.
Starting point is 00:45:20 All right, so let's continue diving into object-oriented anti-patterns by taking a look at everyone's scariest anti-pattern. The poltergeist. So this is one where classes' heads just spin around in circles, right? Like that's what you need to know about this. And moving on, what's the next one? All right, so this one was kind of weird. Um, I don't know that I fully understood this one when I, even when I was doing the notes on it. So it says that the objects whose sole purpose is to pass information to another object.
Starting point is 00:45:58 So they also are referred to as gypsies proliferation of classes big dolt controller class and they say the typical problem is poor object design now this is where things get interesting they say they can typically be found in classes that are named like manager controller start process initialize now we've talked about this in the past those are all sort of typically bad practice things to do. But here's the thing. They say to remove one, get rid of it, move its functionality into the invoked class, right? Either through inheritance or mixin, like Outlaw said earlier, if you're talking about a mixin, it's typically like some sort of composition type thing where things get added to a class, right? But here's the thing, like they even said in the Wikipedia thing, like, don't get this confused with like MVVM patterns where you have objects
Starting point is 00:46:58 being passed from like a view to a model or a model to a view or whatever, right? And I was trying to think about this, and the only thing that I could come up with is if you have, like, an init method in an object that literally just creates some stuff to throw it away right after it's done. Like, it really doesn't serve much of a purpose other than just be passed along somewhere else. Like, I couldn't come up with any great examples of this. No, I mean, like I'm listening to you describe this and I'm thinking like, okay, is this
Starting point is 00:47:34 a DTO? Right. That's something that was sole purpose is to pass information. But I guess the point here is it's not the DTO would be the thing being passed. Whereas this is saying that this object does the passing, which made me think like, okay, well, is this a poorly used mediator, maybe? But then like in the example, I pulled this up in the Wikipedia to see like, well, what they were saying about it. And they were saying, well, maybe the developer anticipated some complex architecture. And so they broke things out so that this method could act as both the client and the
Starting point is 00:48:13 invoker in a command pattern and never did it, never actually separated it. Yeah, it just so, yeah. I guess, what was that? It kind of goes along with the you ain't going to need it thing, but where you break apart things into, you know. Oh, you start. Okay, I know what you're talking about. Like you break it down into crazy amounts of layers and you never even really end up needing any of them.
Starting point is 00:48:44 Yeah. And so maybe that's kind of this type of thing so here's the thing like i found sourcemaking.com has a thing called the with an anti-pattern setup and they have an example called the peach kenner controller and what they're saying is basically if you think about this they have this process timer which i guess would be like a manager type class right and it looks like peaches washer peeler chopper canner they all hook through this process timer and then there's this peach canner controller thing and it's doing some sort of rule thing and it seems to loop through this process timer and then go back through all these classes and it says it has redundant navigation
Starting point is 00:49:32 paths to all the other classes in the system all of its associations are transient and it has no state so it's a temporary short duration class that pops into existence only to invoke other classes through temporary associations. So I kind of get it. Yeah, their example is actually more confusing to me. Yeah, I'm not so hot on this one. And actually, it reminds me of a lot of things that we talked about when we talked about different layers in the clean architecture where we've got these layers that all they do is kind of pass like these DTOs to one other thing, but it's not worthless. Like it's providing this obstruction layer that, you know, we're very intentionally doing this kind of strange thing for. And all
Starting point is 00:50:15 the examples I see are all like, these are short-lived kind of unnecessary adapters. And I don't know that I've ever really seen that. Yeah, I know. Cause I was actually thinking about this as a, not necessarily a rules engine, but, but we've seen things right where there, there might be a rules processing type thing where, yeah, it is going to flow through many classes because its whole job is to process all those rules, right. To make sure that those things happen. So I don't know, like this, this one sort of either, either I've not seen very many examples of this thing. And so maybe it truly is a poltergeist just because nobody has seen it. Right. Like they've, they've all been eradicated.
Starting point is 00:50:54 But I don't know that this one didn't really hit home with me that much. Well, I mean, kind of going along with Joe's point, one example that I was, I was trying to come up with, I'm reaching for an example here, right? And so one thing that came to mind was like, okay, well, maybe they mean like, if your middle tier, right, was so thin, that all it does is take the request from the front end, and just pass it to the back, like no transformation at all. Right. It literally is just passing it to the backend. And then any response is just literally passing that backup.
Starting point is 00:51:34 It's not, there's no abstraction being, you know, happening there. Right. So basically the front end knows exactly what the backend is going to send to it. And the backend knows exactly what the front end is going to send to it, but for whatever reason, they're going through this middle tier.
Starting point is 00:51:49 And maybe that's what they're describing as the poltergeist, but it is a little bit confusing because to Joe's point about the needs of the front end from the back end and vice versa, because you are letting that leak through, that that's why it's a poltergeist. Does that make sense? Yeah, it does. I mean, thinking about it in terms of if we're talking about.NET, right? In many cases, and I know I've advocated for this in the past. So, so, so maybe this will sort of, if this wasn't true, then maybe this would make more sense as a poltergeist. But if you have like an API controller, like a web API controller, typically those things should be stupid, right? They almost are really just a transient class. You want those things calling into either your application tier or someplace to go do something or go get data. And the reason you do that is because those things are only callable by HTTP, and it weren't the fact that those had to be called by a
Starting point is 00:53:08 particular protocol, in this case, HTTP, then maybe that could be considered transient class, right? Like if literally it was just a handoff, like what you were saying, Mike, then maybe that'd be a poltergeist. But again, I haven't really seen that stuff happen that much. I've never really just seen useless layers of code laying around. Now, I've seen over-engineered and over-architected things where you have tons of layers. The more I think about this, the more I think that we have seen this. Really? Yes, absolutely.
Starting point is 00:53:53 Like where? Because I think it goes, I think the key here is that if that information, although it's not described in the definitions here, it's like this, so I could be just reading into it what I want to read. But I think the key here is that if you're literally doing nothing more than passing, okay, here we go. The three of us are all objects, okay? We're all instances of some class, right? And if all I'm doing is sitting between you and Joe, and I'm literally just passing the exact same data structure that Alan gives me, and I'm passing it over to Joe as is. And then Joe passes me something, and I take that same response from Joe, and I pass it back to Alan exactly as is, then what's the point of me being in the middle? I provide no value.
Starting point is 00:54:32 I'm the poltergeist in that scenario. Yeah. And I know that we've seen code like this where – I'm sorry, Joe. No, no. I was just agreeing with you. I think I know where you're going. And it makes sense to me when there's nothing being added. But I think a lot of times we'll see this when there's like a web service layer and it just passes on something to some sort of like core library. But I think a lot of times that web
Starting point is 00:54:51 service, it may do nothing 90% of the time, but sometimes it'll reach in and grab something from like the HTTP request or something that your core library can't access because you don't want to have necessarily a dependency on it being a website. It's got a shared library. And so that web service layer, maybe nine times out of 10, just passes straight through. But that one time out of 10, it does something that's very specific to being run as a web service. And I also think even if it is, even if 100% of the time, it's just passing through, I think it's still nice to kind of have a good clean layer there that says like, you know, my JavaScript front end calls this web service layer and this web service layer goes and gets it from the core.
Starting point is 00:55:30 And even if it's just a straight pass through, I think it's still kind of valuable to have that layer of indirection based on the stuff we talked about with the clean architecture. But I think that's. And being able to use that core library somewhere else, like a command line. Yeah. But I still think that's a different situation, right? Like when you talk about a web service or any kind of, you know, service layer like that, it is adding to it. Even if it's only passing through things, you're still going to have
Starting point is 00:55:55 HTTP responses that happen, errors that could happen, ways that things get handled across that protocol. So I don't think that's a fair analogy for the poltergeist. However, if you were taking something, it hit your web service layer, and then you called another class to say, Hey, go get me data. But then all that thing did was pass across your request to get another class that would feel like the poltergeist. Right. And that's what I'm saying. Like, I don't know that I've seen that in too many places. I'm not saying the web service layer. A lot of times you'll have like annotations for like saying,
Starting point is 00:56:29 Hey, this is a get, this is a post, or this is, has this required security context. And so those things I do think like, that's nice to have a layer that kind of defines those things about these web services. Yeah.
Starting point is 00:56:39 That's outside of your core library. Like your core library, your DL, your dynamically linked library shouldn't need to know whether it's a Git or a Post if it's going to be used by a console application as well. Right. Yeah, so I mean, I think your example outlaw was perfect of, you know,
Starting point is 00:56:55 you're just taking data and sending it along, right? Like you're adding zero value. You're literally nothing more than a middleman. You don't have to make it personal, but... You know what I'm saying. Yeah, exactly. But you as an object are not valuable. You as a person is invaluable.
Starting point is 00:57:11 So, yeah, it's – I don't think I've seen that. I don't know that I've ever seen just completely throw away code like that that was doing nothing more than passing stuff back and forth. Okay, so how about this if you uh listeners uh listening to this podcast right now i've ever heard of or seen an example of a poltergeist or a gypsy or a proliferation of classes or a big dolt controller class and let us know in the show notes and drop a comment here on the post slash episode 79 and you might also win a book. Yep, and they've got to exist, right? It only is an anti-pattern because it's been done.
Starting point is 00:57:52 So it's there. We just haven't found it. All right. Well, moving on to sequential coupling, and this is my favorite because I know I've done this so many times, and it's not good. It's a class that requires its methods to be called in a particular order. And so the example that I came up here that I know I've done before and I knew it was bad, at least after the fact, is I've got an SDK, like a credit card processor, where you have to do things like create a new client, like initialize the SDK. And then you create an order and then you add items to the order and then you create an order, and then you add items to the order, and then you submit the order for authorization, and then you submit a capture.
Starting point is 00:58:29 And these things might all be going through like the same object. So these would be like five different methods. And you can't go out of order. You can't capture before you authorize, right? You can't add items to an order that you haven't created yet. And so, you know, obviously in this case, like there's, there are reasons why those things need to happen in that certain order, but by having a single class that has all those methods and you're leaving it up to the developer to figure that out and do things in the right way. So how do you know when you're doing that? Well, if you catch yourself saying something like,
Starting point is 00:59:04 oh, it's because you didn't to the developer who's you know complaining to you so they come to say like hey i called your web service and it broke and you're like well you didn't initialize the flipper dee do da first like well i didn't know i had to do you know do that it's because it wasn't obvious from your api i feel like the web the web apis though might be like the worst like the web APIs, though, might be like the worst. Like public web APIs might be a really bad implementation of that, but I know where you're going with that. And I only say that because depending on the API you're using, some of those you have to create a session first and then pass that session identifier in future requests or something like that, right? Right. So, right.
Starting point is 00:59:46 They, and, but I guess maybe to your point, maybe you are right. That, that is an example of sequential coupling, right? Like you can't just call their search API without passing in the identifier of the set.
Starting point is 00:59:58 Well, here's another way to do that, right? So the example of the credit card where we initialize, we create an order, we add items to the order, we submit the order for off credit card where we initialize, we create an order, we add items to the order, we submit the order for auth, and then we capture. Well, why don't you have one object that says like create client, you call that method, and it returns to you an object,
Starting point is 01:00:15 or sorry, an order creator. And then use that to create your order, which returns you another object, which is like the order accumulator. And you add your items to that, which returns to you an object called the auth maker. And so there's kind of no way for you to get this wrong at that point, right? It guides you via the API that they provided to doing the right thing. That's not very flexible, though. Yeah, you only have access to the next step after you did the prior one. Right. Or another way you could do it as well is just make sure that you only have a method that says, hey, you know, charge this order.
Starting point is 01:00:53 But then you have to pass in all the relevant information in the first place for it to do it. Right. Which might be uglier. You know, maybe only the fathers and mothers listening might get this, but if anyone else, while he was describing all of these like, you know, Authenticator and Order Maker and Alan's looking at me like I'm crazy. I've never heard these names that you're talking about. The Heinz Doofinators. No, no, yes.
Starting point is 01:01:39 Good. I'm not the only one. I think it would be yes, no, no. Come on, man. Nobody, Phineas and Ferb? Your kids don't watch Phineas and Ferb? No, I was a Berenstain Bear fan. That's right.
Starting point is 01:01:55 Well, I'll give Joe the pass here. But, Alan, you have no excuses. I don't know what my kids watch. Nope. Moving right along yes so another way to fix this is the template matter template method pattern which we talk about all the time it's one of our favorites where you can have a bunch of hooks basically that you can kind of have so you might have an object that says hey this is uh the the credit card process. And now you can override methods or you can implement methods for on create order or on before add items to card
Starting point is 01:02:33 or something like that that happened in a specific sequence. That way you're enforcing the sequence. And so you're kind of forcing the client to do the right thing in the right order and you're not just leading it up to them to read the docs. And another example here I kind of thought of is if you've got a class that's maybe got some data that needs to be set before you can do a behavior, like say that color class, like I allow you to create a new color without passing any arguments.
Starting point is 01:03:02 So you've just got a color, you know, that's got nulls for the R, G, and B. And then I've got a method like, you know, to pretty string or to string or to screen or something, draw. And, you know, you try to do it right off the bat, you say new color and then color.draw and nothing happens. Well, I'd say, well, it's because you didn't initialize me. Well, you could have made it that a constructor, if that was required, if you need information from the callee to do your job, then you can make that required via constructor. Now I know in a DI world, we talk about this all the time, how that's kind of a no-no in some ways, because it's not very flexible and not very composable. So I think that's kind of unfortunate and uh although you want to know something uh from the di so after we did all this architecture talk in the past i was looking at various different
Starting point is 01:03:53 ioc container frameworks for dot net right and there's the big ones there's unity there's ninja there's castle winds or whatever well i was I was looking at auto fact and there was something that was really interesting about that is if you're doing DI with auto fact, it will always try to use the constructors with the most parameters or arguments so that it has available. So if there's a constructor that has 10 parameters in it and it has all 10 of those things, it's going to use that one. If it sees that, Hey, I only have nine of them, then it's going to drop down to find the one that next fits the biggest bill or, you know, the most that it
Starting point is 01:04:37 can fill out, which I thought was really interesting. And I maybe unity and those other ones do the same thing. I don't know, But it is interesting. You really kind of have to intimately know your DI frameworks if you plan on using those things. Yeah, and I guess I don't usually do the constructor type stuff when I do the DI. I usually just kind of have a couple properties, and then I tag them with an annotation or something that says auto wire. So whenever I ask for that object, it gets populated by whatever it needs. So I don't usually use the constructor thing, but there's really not a reason not to. You still could enforce that,
Starting point is 01:05:12 and then it's up to the DI library. But constructors are kind of weird because now you're relying on something that's very specific to the class and not the interface. Because you can't, as far as I'm aware, have an interface with constructor methods in it that's totally outside of like the interface only represents the behaviors and the properties i don't think i ever thought about it like that no we've definitely talked about this actually
Starting point is 01:05:36 yeah there was definitely like a what if conversation i'm sure that we have yeah it's just not coming back to me though so here's what you need to do. Episode one, Eyes for Interface. And yeah, you can listen to that and hear our take on it then. I'd forgotten about that. Yeah. Yeah, because Joe had- I spent like 12 hours prepping for that episode.
Starting point is 01:05:57 Joe had like a whole list of wants, if I recall. Yeah, he did. That's right. That's four years ago. That's a good memory going on five yeah yep so that's it for sequential coupling all right so with that let's move on to exhibits object-oriented anti-pattern this is a yo-yo problem yo dog i heard you like anti-pattern so i put an anti-pattern in your anti-pattern. So this is a structure that is hard to understand due to excessive fragmentation.
Starting point is 01:06:34 So have you ever read some code, program, et cetera, that was so complicated that you had to bounce back and forth between files, within the file, classes, et cetera, to understand this. Right? That's the yo-yo problem. Right? I've got an amazing example. Okay. And Alan's going to remember this as soon as I start saying it.
Starting point is 01:06:56 I don't think you ever saw it, Alan. Okay. We had the pleasure of working with some source code. And it had this crazy inheritance chain. So, let's say you had like an order processor and the order processor inherited version seven of the order processor, which inherited version six. Truly, labeled version seven. Order processor V7.
Starting point is 01:07:17 And then four. And so you would start in your order processor and say, okay, process order. And it would call an internal method. You look in the file and say, I don't see this method in this file. Let me go check number seven. Say it's not here either. Let me check six. Okay. There it is. Now it calls another method. Let me go back to my current version. Oh, there it is. Okay. So it's overriding here and so every like stupid method that you looked at in this thing you possibly had to chase this thing down version version version version until you got to the kind of the root and sometimes it's at the top layer sometimes it's
Starting point is 01:07:55 somewhere in the middle sometimes it's at the very bottom for core type stuff so like as soon as i you said that first sentence i was like like, oh, my gosh. I know this. Flashbacks. Yeah. So how can we avoid this, right? And so this kind of comes back to some of the conversation that we've had already, which is maybe, you know, the S from help to help keep your objects smaller, right? Because if you're adhering to the S, the single responsibility principle, then maybe you're not suffering from God objects, cesspools, etc. And so maybe just in that alone is keeping the less, and therefore the lines of code smaller. But another one was maybe, and I think I even mentioned this earlier, maybe it was the God object, Alan. Favor composition over inheritance so that you can keep your inheritance tree as shallow as possible,
Starting point is 01:09:03 which to your example, Joe, you were describing the inheritance problems in that framework. So yeah, maybe if you favor composition over the inheritance, then it'll help with that, right? Like, hey, where did this method come from? Oh, I don't know. It came from, not the one class that I inherited from, but, you know, somewhere up in the hierarchy, there's this method there. Oh, that's where it's coming from. And you know what? For people that don't know these terms of composition over inheritance, inheritance is when you have what you're taught in school, right?
Starting point is 01:09:38 You have your subtype or your base type and then your subtypes, your supertypes, all that, right? We're literally everything down below. You have a person, then you have an employee, then you have a manager, you have whatever, right? Those are all inheriting things. Well, to say that they, like, you know, human is the base and person, or I guess that's maybe too far. Well, no, human's good. Human's good. It's something with two arms, two legs, whatever, right?
Starting point is 01:09:59 Then a person's going to have a name, and then, you know, you go on from there. Right, but I was going to say that it inherits, depending on your language, you might see language like a person inherits, you know, animal and Mike inherits person or, you know, it could be extends maybe. But yeah. Yeah. So that's inheritance, right? Everything that goes down from that base level thing gets the behaviors of everything above it. Right. Everything that goes down from that base level thing gets the behaviors of everything above it. Right. The composition is it earning class or something, instead of that, you tack on an object to the employee class that is, you know, earning. And then that thing could accumulate wages and whatever else over time. So it's almost like a plug-in thing that can add behavior to a
Starting point is 01:11:06 class instead of inheriting up the chain from a bunch of other things above it. And there's a big argument over which is better, right? And that's probably for another topic, but I did want to at least point it out because it's easy to throw those things out. And if you haven't been exposed to the sides of the worlds of that, then you might get lost. Yeah, I wanted to throw out too. We've mentioned just about every other letter of Sol this episode. This is a major, major violation of Liskov's substitution principle, which says that any object should be substitutable for its parent. So if, you know, order processor seven behaves differently than order processor six, it's parent, and that's a violation. It's saying you cannot just substitute either one for the
Starting point is 01:11:53 other because it's behaving differently just by the nature of me doing these overrides. And I also wanted to mention too that I've actually, you know, I throw some shade on this thing. I absolutely did the same exact thing when I worked for a small web firm. And we had a bunch of different clients that would use common code. So what we would do is like we'd spin up a new client. And of course, they had differences from the other clients. So I would bring the core code over. And sometimes there would be like a version one or version two.
Starting point is 01:12:19 Or if there was another client that was similar, I would copy it over and then kind of have this other layer of the custom code that was specific to this customer, right? And it let us do things really quickly. But it was also a really bad anti-batter because I didn't have the tools and the knowledge necessary to do things in a better, more composable way where I could have kind of swapped classes, smaller classes in or out.
Starting point is 01:12:40 I had these big kind of, you know, basically everything we talked about tonight not to do. I had big God objects that, uh, were orgied together. Is that how you say that? Uh, there's absolutely some sequential coupling going on and absolutely there was some yo-yos happening. And so, you know, I doing, knowing what I know now, I would definitely try to do things better. Uh, and definitely had some problems because it was really hard to work on and really confusing. You would not be able to really clearly tell what exactly was happening for even the most minor things. That makes sense. Because basically it sounds like you were kind of hacking in things that you needed for each customer just based off the pipes that were in place for the other ones.
Starting point is 01:13:25 Yep. Like, oh, this customer doesn't charge tax because it doesn't make sense for them. So in methods 13, 14, and 17, I need to make sure to just zero that out. So I'm just going to override those and change that one line. But the way I would override it was to copy the method down to the child. And that method might have seven lines in it. I would change the one that I needed. Well, guess what happens when now I have changes that need to be applied to all my clients.
Starting point is 01:13:48 So I go and I change it in layer three. And I didn't change it in layer seven because I forgot that this particular client overrode this function. And it didn't get the fix that I've now applied because it's a direct copy and paste from, from an earlier ancestor. Yep. So don't do this. Nice. And I've done it. All right.
Starting point is 01:14:13 So the, uh, the resources we like or yeah, go ahead. Yeah. I feel like we kind of got lost though on that one though. I mean, right.
Starting point is 01:14:21 Cause the, the, the big problem here about the yo-yo problem was just like the over the excessive fragmentation right yeah i got hung up on the inheritance part but that's just one kind of face of this happening so it reminded me of an example but it doesn't have to be just like you said like there's definitely times too when i've had stuff where absolutely like especially i guess maybe if you've got some poltergeist in there you end up having multiple files open for one small thing well i, the reason why I kind of wanted to circle back to that was because going back to some of our conversation during the Clean Code series,
Starting point is 01:14:56 right? I don't remember exactly what the line was like. I remember Uncle Bob had some kind of amount, you know, like his ideal length for a method, for example. And then, you know, that was what was printed in the book. But in, you know, comments that have been or blog posts or whatever, I don't remember where it was said, but he'd actually revised that to be a much smaller number where he's like, oh, you know, ideally they're like three lines long. And so then that made me think like this yo-yo problem, the excessive fragmentation, well, then does that apply to like, if you have your class to where everything, every method is so small, like you have this extreme fragmentation between it.
Starting point is 01:15:45 Well, is that good or bad? Right? I mean. Well, within one class, I don't think bouncing around in one class is necessarily bad as much as bouncing around through your entire file system. Right? Unless we're talking about a class that's got 10,000 lines of code. Like, I think this is one of those things that you got to treat and, you know, in just what's a reasonable sense, right? Like if you broke out your methods so that it's easy to read and like the, the whole newspaper thing, right? Like you can read the
Starting point is 01:16:16 headings and you know exactly where it's going. I don't think that's the yo-yo problem, but if it's, if it's a bunch of names that don't make sense and so you're bouncing around in a file back and forth all over because things weren't weren't uh expressed well then maybe that is so i think it could happen within a file i don't think there's any rule that says it wouldn't but then again i didn't look at the wiki page either. So, yeah, I'm very familiar with kind of scrolling up and down and up and down. And I typically like things to be in multiple files because at least I can have different tabs. If I'm going to going up and down some sort of behavior,
Starting point is 01:16:55 some sort of, uh, Oh, my friend, you can have the same file open in multiple tabs. Yeah. I don't like that though. I do.
Starting point is 01:17:04 I already have like 30 frigging tabs up, but i don't like that though i do like i already have like 30 freaking tabs up but i don't want to have duplicates okay yeah i'm putting my foot down there yeah well i mean it was just it's definitely made me wonder because like uh especially with the newspaper principle right you know if you start pushing that method down to, you know, all of the things that might call it or above it, then it could be way down below the fold, you know, and you're like, okay, let me, wait, what did that method do again? And you're scrolling down for, oh yeah. Okay. Now let me go back up, you know, um, yeah, I, that was the only reason why I was thinking like, well, where do you stop this, right? Like, does it have to be, since inheritance was brought up as the go-to example here, even in the definition of it, then does that imply that it has to be between objects or classes, rather, in order for this to be an issue not necessarily within the method but
Starting point is 01:18:06 yeah okay cool okay so resources that we like we'll have a link to the wikipedia article where we pulled these from and you can read more about it here on the wikipedia article or also on episode 79. Yep. And with that, it's time for Alan's favorite portion of the show. It's the tip of the week. Yeah, baby. Alright, so I'll go first, and if you like Visual Studio Code like I like Visual Studio Code, this is going to be the extension for you. A friend of ours turned me on to this amazing extension.
Starting point is 01:18:51 This might be, hands down, one of the best extensions that I've found for Visual Studio Code yet called GitLens. It is amazing. Any line of the file you're in, you can just see who changed it, when they changed it, what the commit was, all like kind of shadow, quote, shadow texted, you know, to the right of the actual code. And, you know, you just hover over that thing and then it'll pop up a little window and it'll show you the actual commit. And you're going to be like, oh, really? And then you click on the commit, and you can see all the details. Like, this thing is awesome.
Starting point is 01:19:29 It's a must-have. You must get it. Right? Yes. I don't know what else I could possibly say about that. Excellent. So we'll have a link there. All right.
Starting point is 01:19:42 Mine is kind of interesting. This might be putting the cart before the horse because we haven't done an episode on Docker yet, but we plan to because it might be taken over the world. So there's a tool called compose. So if you know Docker at all, there's Docker and Docker files. And then probably the next evolution that you'll get into as you go down your learning path is Docker compose. And then after the next evolution that you'll get into as you go down your learning path is Docker Compose. And then after you learn that, you're going to realize that, oh, that was cool and all. I learned how to set up my little environment.
Starting point is 01:20:13 But now I need to scale that. And now you're going to be getting into something like Kubernetes or Docker Swarm or whatever. Well, here's the interesting thing is if you've gotten in and you've learned Docker Compose, so now you know how to set up multiple containers that can all communicate with each other. There is a tool at compose.io and that compose YAML files that you had created, and it will turn it into Kubernetes friendly stuff so that you can then spin up your, your pods and Kubernetes by just using your Docker compose files. So it's like a conversion tool. So that's really cool stuff. Um, I'll have the link for the compose.io here. And then there's another user guide directly from the Kubernetes.io website that they recommend using this thing.
Starting point is 01:21:10 So that's very cool. And then a secondary tip that's really just you've probably seen it and ignored it many, many times. When you open up Visual Studio, there's typically a start page there. And at least in mine on the far right, there's like developer news, all kinds of stuff that comes through there. Man, take a look at that. Like there's some really good stuff that comes through there. There was a, and today when I opened it, there was a machine learning thing in there that was like a three-part series on, you know, Hey, so man, this is another tip I should put in here. There's a thing called Kaggle. Kaggle is a site where they have these machine learning competitions.
Starting point is 01:21:51 So it's really cool. And it's K-A-G-G-L-E.com. I think Kaggle.com. All right. And they have all these things up there that they basically want people to solve with machine learning. And if you solve it, some of these things, you can get paid a decent amount of money to do it. It's like coding competitions for machine learning. Well,
Starting point is 01:22:12 the interesting thing is one of the pieces of the article in this dev news on the side of the visual studio thing was this machine learning thing. He's like, Hey, how I came in second place in 22 minutes using Azure machine learning or something like that. So, you know, really cool stuff in that side thing. It's a free resource. I mean, just if you start up Visual Studio, take a look over there at the developer news.
Starting point is 01:22:36 There's, you know, there's hacker news and all that. And then there's this stuff and there's some good nuggets buried in there. Very nice. Well, I'm stealing my tip of the week from Arlene Andrews. Thank you very much, Arlene. And this is Flavio Copes. We'll have a link in the show notes. Chrome developer tips.
Starting point is 01:22:58 And if you go to this webpage that we'll have in the show notes, you open it up, there's like 12 tips here. And some of these are really good I didn't know about like, you can debug on DOM modifications. So if you go to this article, click on that heading, it'll take you down to this little like GIF or video showing you how you can right click on a DOM element in Chrome and say, break on modifications. So whenever that DOM element, for example, gets modified, it's going to break as if you had like a debugger statement. And that's just one example. You can also do things like that I didn't know about for like AJAX requests, XHR, fetch debugging. So you
Starting point is 01:23:36 can say, hey, whenever this particular string pattern calls a AJAX call or a web service, go ahead and break so So I can like, look at what's being passed in or coming out. Um, there's also watch, which I never use in Chrome. Like I'm always like doing console, like basically writing out the state of variables. Uh, and now I'm like, why didn't I just use the watch? It's probably right in front of my face, but that's just like three of the, like the 12 or 15 tips they've got here. And each one is really easy to understand. It's got like a little video that shows you exactly what to do and exactly the
Starting point is 01:24:10 benefit. And it's just straight up tip after tip after tip of awesomeness. These are amazing. Some of them. Yeah. There was, um, the episode 50.
Starting point is 01:24:21 If you remember that, Nope. There was episode 50. My tip of the. Nope. There was episode 50. My tip of the week on that one was break on attribute modifications, which is pretty much what you're describing, where you could right-click on it and put a break point on it when this thing changes. If I can only remember half the stuff I learned,
Starting point is 01:24:40 I mean, good shape. No doubt. I actually, hey, by the way, somebody asked if, hey, would you guys add a search to your site? So it's there. We might move it eventually. Yeah, we should definitely move it. Yeah, right now it's sort of below.
Starting point is 01:24:58 It's about midways down the page on the right-hand bar if you're on a computer. I vote for top right. Yeah, that's probably where it should go. So anyways, I use the search a lot on our site because i go back and look at our tips that we've done so yeah we also do a lot of tagging uh for episodes and also if you're looking for something specific you can say like hey what was that one thing that you don't remember you guys were arguing about and we'll probably be able to figure it out at least pretty close now what so here's it's somewhere buried this two and a half hour episode now here's the one that here's the feature that i want that I'm trying to see if it's in here.
Starting point is 01:25:27 And if anyone from the Chrome dev team is listening to this, I'm going to tell you now because I super, super badly want the feature where if you are, how to describe this, if you want to see the DOM change, so you have the actual page window available and the Chrome DevTools where you can see both, and you want to hover over something and based off of a hover over action, that changes something. And then you want to go and click into the DOM. I want an action where you, like a button where I can tell Chrome, hey, stop listening to events right now because I got to move the mouse. Do you know what I'm trying to describe? Yes. Leave it in the hover state or whatever. Yeah. So like, for example, if you had a hover over a glyph or something that would bring up
Starting point is 01:26:19 a menu and you're like, oh, cool. Now I want to inspect this menu, but I want to go inspect it in the dev tools. I want to go inspect it in the dev tools i want to play with it over there as soon as you move your mouse off that menu then the menu is like oh time to go away there's probably a shortcut that we don't know about man i would if someone knows of one i would love to know how how to stop chrome from processing the events. Just freeze it. How much you pay me? I'll find it. Oh, I gotta pay you? Freeze stickers. Well, this is why we can't have nice things, people.
Starting point is 01:26:51 That's right. Excellent. Cool tip, man. Well, cool tip, Arlene. Thank you. Yes. Oh, go ahead. Oh, you. Alright, Alan. No.
Starting point is 01:27:04 Alright, well, I'm gonna go. Oh, you. No. All right, Alan. No. All right. Well, I'm going to go. So we hope you enjoyed this episode of Anti-Patterns. And there are other episodes of Anti-Patterns. This happens to be the first one that you've listened to. But you can go back and listen to some of the back catalog. Aside from that, subscribe to us on iTunes, Stitcher, and more using your favorite podcast app.
Starting point is 01:27:28 If you haven't already, we would love to get a review from you, so you can be sure to leave us a review. You can visit codingblocks.net slash review to find links to your favorite podcast aggregators. Yep, and while you're up there, check out our
Starting point is 01:27:43 amazing show notes, our examples, our discussions, and even more. Yeah. And bring your feedback questions and rants to the Slack channel. We've got a lot of people who join and stay kind of quiet, but don't be afraid.
Starting point is 01:27:54 You can just come in and say almost anything. Just be nice. Just come in and say hello and get the ball rolling. That's really the key, right? Be nice. Yep. Be nice. And make sure to follow us on Twitter. And everyone is nice, by the way.. That's really the key, right? Be nice. Yep, be nice.
Starting point is 01:28:05 Make sure to follow us on Twitter. And everyone is nice, by the way. That makes it sound like it's not nice. But I didn't want to say anything just because we like it nice. It's nice now. We want to keep our place nice. Oh man, you made it weird. I made it weird.
Starting point is 01:28:21 I'm not the one who said it can't be nice. Well, whatever whatever make sure to follow us on twitter at coding blocks or go to the website codebox.net you find our social links get off my lawn i think you mean check us out that's right check us out

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.