Summary
In this episode, we continue our discussion on practical object-oriented programming techniques, focusing on granularity and designing interfaces. We explore the concept of building with bricks or building with sand and its implications on object-oriented design. We also discuss the importance of considering cohesion and coupling when designing interfaces.
Detailed Notes
In this episode, we continue our discussion on practical object-oriented programming techniques, focusing on granularity and designing interfaces. The host, Rob, emphasizes the importance of considering granularity when designing interfaces, comparing it to building with bricks or building with sand. He explains that interfaces should be designed with the right level of granularity, taking into account the needs of the developers who will be using them. The host also discusses the concept of cohesion and coupling, explaining how they relate to object-oriented design. He encourages listeners to think about granularity when designing interfaces, but it's not clear what specific strategies or techniques he is recommending.
Highlights
- Granularity in object-oriented programming
- Interfaces in object-oriented programming
- Cohesion and coupling in object-oriented design
- Building with bricks or building with sand
- Designing interfaces with granularity in mind
Key Takeaways
- Designing interfaces with the right level of granularity is crucial in object-oriented programming.
- Cohesion and coupling are essential considerations when designing interfaces.
- Interfaces should be designed with the needs of the developers in mind.
- Building with bricks or building with sand is a metaphor for designing interfaces with the right level of granularity.
- Designing interfaces is a critical aspect of object-oriented programming.
Practical Lessons
- Consider the needs of the developers when designing interfaces.
- Design interfaces with the right level of granularity.
- Think about cohesion and coupling when making design decisions.
- Use metaphors or analogies to help explain complex design concepts.
- Encourage developers to think critically about design decisions.
Strong Lines
- Designing interfaces with the right level of granularity is crucial in object-oriented programming.
- Cohesion and coupling are essential considerations when designing interfaces.
- Interfaces should be designed with the needs of the developers in mind.
- Building with bricks or building with sand is a metaphor for designing interfaces with the right level of granularity.
- Designing interfaces is a critical aspect of object-oriented programming.
Blog Post Angles
- The importance of granularity in object-oriented programming
- Designing interfaces with the right level of granularity
- Cohesion and coupling in object-oriented design
- Building with bricks or building with sand: a metaphor for object-oriented design
- The role of interfaces in object-oriented programming
Keywords
- object-oriented programming
- granularity
- interfaces
- cohesion
- coupling
- design
- development
Transcript Text
This is Building Better Developers, the Develop-a-newer podcast. We will accomplish our goals through sharing experience, improving tech skills, increasing business knowledge, and embracing life. Let's dive into the next episode. Well, hello and welcome back. We are continuing our season where we're looking at practical object-oriented programming techniques and getting into some of the basics of it and just how to apply these, mostly with an eye towards the design side of it. But we also talk about implementation as well. This episode, I want to continue talking about interfaces a little bit. And this is going to be a, we're going to touch on a couple of concepts that we've seen now already and we'll continue to see through object-oriented. It really comes down to what we'll call granularity. It's basically how big or small should classes be and how that really affects how you can use them together. It's also, I've had discussions with people in the past where it's sort of the idea of building with bricks or building with sand. And by sand, I mean not like trying to build sand up, but actually use the sand to create the bricks and then the bricks to create the walls or the building or whatever it happens to be. So it's definitely a, it's a granularity thing. And it does have, it does really start touching on some of the ideas of like cohesion and coupling and some things like that that are different approaches to object-oriented programming and basically an object-oriented design for your solution. Now with respect to interfaces, really specifically, a lot of what I think the best approach that I experienced was when you go back to early Java, when they were just starting with the swing interface and they had these event listeners basically. And while these were not actual interfaces, they were ways to essentially to register your, as an object, as a class that I want to support X. And it was actually very useful. And it's just a real good design as when you think of classifying essentially methods and functions. And we've talked about these, I'm not talking about them as classifications, but we've talked about things that are examples. Good example would be saving and loading. So if you have a, which you may refer to as like a persistence. So you could have a persistence interface that provides typical persistent things, which we save, load, maybe load by ID, create a new, you know, something like that, sort of crud type tasks. And we see those used a lot with a lot of the templates and things like that, that you see in various frameworks where there are a specific set of methods that are out there that if your class implements them basically, or utilizes them, then it gives you this overall functionality, i.e. persistence in this case. You would also see this in, you see this classification or this grouping of functions in a lot of areas. In the business side, you would see things like an invoice. There are a set of invoice functions that are pretty global in a sense, because if you have an invoicing system, then you have things like creating an invoice. You have line items for an invoice. You have sending or submitting an invoice. You have paying for an invoice. You may have partial payment on an invoice. But you have these series of functions that allow you to take these smaller granules of functionality and combine them to a slightly bigger brick of functionality. So that you don't have to go through necessarily and worry about each of those individual aspects of it. From a designer point of view, what you get to do is you group those in and say, essentially to your developers that are utilizing it, if you were going to do X functionality, then these are the things that you need to support to do it within our environment, which not only is a within our environment, but may also be just a general good thing to do. When you think of, for example, an application user, there are things that you're going to see pretty much across the board. And a simple one may be things like a password, a user name, some sort of profile stuff, like maybe an image or first name, last name, email address, phone number, some things like that, basic contact information. And it would make sense from a framework point of view or a library point of view that if you want to support a user, then these are the things that you have to be able to implement for your specific user type. Now remember, this is with an eye towards not necessarily root objects or the base objects. These would be things that have inherited. And of course, with an interface, remember, it is a sort of, this is a form of inheritance, is that you have this functionality that you're not exactly inheriting because you have to, when you sign up for it, typically by saying, hey, I'm going to implement this interface, you have to actually write code that ties your object to or your class to that interface. A simple one that we see a lot would be things like the ability to sort. If you sort classes, you have to be able to compare them. It's one of those things that may not jump out at you initially, but it becomes very obvious very quickly. For example, if I wanted to sort a list of numbers, I know, whether it's ascending or descending order, I know, we all know that one is less than two, three is greater than one, things like that. So that we know how to order those, how to place those items for that collection in an ordered fashion. If I want you to order colors, if I wanted you to sort a list of colors, that doesn't become necessarily obvious. We have seen that because if we spend any time in programming, we probably understand things like RGB numbers and things like that that would allow us to maybe convert a color to a hex and then we can sort by hex order. But then think about inventory. How do you sort items in inventory? You may have these internal IDs, but there may be something else that allows you to compare them. How do you sort a list of automobiles? You want to have some method that relates to the end user. So they would look at it and say, okay, if I wanted to walk through a list that I knew was ordered, then I would expect these things to be at one end of list and these other things to be at the other end of the list. So we would have to, in a sort interface, we would have to have something that allows us to compare two items to know which one comes first. And there's little things like that that we don't really need to deal with, like for example, comparison. We don't really need to deal with it unless we have certain interfaces we want to implement. So this allows us to create an object, create a class and put some basic stuff into it. And then as things inherit from that class, they can always add in implementing certain interfaces. For a base object itself, just a data object we've sort of talked about in the past where it has maybe an ID, a creator, user that created it, and maybe a last update or a creation date. Then, and with that, we don't really necessarily need to worry about sort or compare because we, I guess we could do it by ID, but we're just going to say that this is such a minimal piece of functionality. We're not even going to bother about listing just pure data objects. But as we get further down the hierarchy, there's going to come a point where we do. So if we inherit from data, let's call it phone number. So we have phone number and we inherit that from data. So we get an ID and a user ID, user that updated it and last update date and creation date. And now we add maybe the three parts of a phone number. The prefix, the base and the suffix or whatever those are. Now we may want to sort and add a comparison that allows us to compare across those attributes of a phone number. In so doing, we at that point will implement the interface. We don't have to do it up at the root level or at the base level. There's other things we can do. We may want to implement up at a base level and then allow an interface and then allow further down the chain for things to override, for example, the comparison and things like that or just leave it as it is. This is the thing that we need to be considering as we build out an interface. We want to be able to provide this functionality at the right level of granularity. We don't want every little function. For example, sort. If I want to be able to sort items, then I have to be able to compare. So it doesn't make sense for me to have sort without compare. But do I need to have a compare without, if I'm not going to sort, do I need to have a compare? And this is that design discussion you need to have. Do we need to have an interface for compare and an interface for sort or can we just create a sort interface? This goes back to my statement earlier when I was talking about the swing and how they did it is there are certain groups of events that made sense as a collection of them. So if you allowed, for example, think of a graphical object. If you allow a click, then you probably should have within your interface, you should also support double click and right click and like a control click or a shift click. So there's a family of click events. It would make sense that if you have support for one in the interface, then you're essentially going to support all of them. It doesn't mean you have to fully do anything different with any one of those. Like a double click doesn't have to be different from a single click. But it does say that if I'm supporting a click at all, I need to have something that specifically essentially handles or does not handle these other related events. It allows you to really to talk to the developer in a way to say, look, if you're going to do X, these are the things that you also need to do in order to support that properly and fully. And while you may not have thought of these other things, you need to. You need to consider those and be intentional when you do your implementation. And we can go on for quite a while. And we may come back to this, particularly the granularity discussion. I think we're going to see this on a couple of different occasions. But with interfaces in particular, I wanted at least start getting that to percolate around in the back of your brain as we're talking about design and some of these other features of object-oriented software. The idea that we can make these very granular things where every function is a class or an object or an extension or an interface, or we can make it a little more intelligent and group some of these functions and these methods so that it's much easier for the developers to see it. They can go to one class or one interface and see, oh, these are the things that are related to it. I implement it and I'm off and running, as opposed to them having to basically a la carte their way into a design. And there is arguments on both sides of that. But I wanted to at least get that percolating around in your mind. Over the course of the week, the most recent design you've worked with or created, look at it with an eye towards granularity. Did you maybe make something that had a lot more classes and options than needed? Or did you do something that was a little more simple and straightforward where there were fewer but more powerful objects, classes, interfaces that you created or that you designed? And I'll do it this time around. We'll just add some more to canoodle about and get you thinking as we try to become better developers, especially in the object-oriented world. But as always, go out there and have yourself a great day, a great week, and we will talk to you next time. Thank you for listening to Building Better Developers, the Developer Noir podcast. For more episodes like this one, you can find us on Apple Podcasts, Stitcher, Amazon, and other podcast venues, or visit our site at developernoir.com. Just a step forward a day is still progress, so let's keep moving forward together. Hi, this is Rob from Building Better Developers, the Developer Noir podcast. We're excited to be on Alexa now. You can enable us by simply saying, Alexa, enable Building Better Developers, and we will be there ready for you every time you want to listen to your now favorite podcast. Whether we are your favorite podcast or not, we would love to hear from you, so please leave a review on Amazon.