🎙 Develpreneur Podcast Episode

Audio + transcript

The Challenge of Statics

In this episode, we discuss the challenges of using statics in object-oriented programming. We explore the limitations and potential issues with class-level variables and methods, and discuss alternatives such as singletons and message bundles.

2021-03-29 •Season 14 • Episode 480 •Object-Oriented Programming •Podcast

Summary

In this episode, we discuss the challenges of using statics in object-oriented programming. We explore the limitations and potential issues with class-level variables and methods, and discuss alternatives such as singletons and message bundles.

Detailed Notes

In this episode, we discussed the challenges of using statics in object-oriented programming. Static values and methods can be problematic when multiple classes rely on them, and can lead to issues such as tight coupling and difficulty in extending or modifying the code. Singletons and message bundles are often more effective alternatives, as they allow for more flexibility and maintainability. We also touched on the use of constants classes for enumeration, but noted that ideally these should be defined within each class rather than at the application level.

Highlights

  • Static values and methods are not always the best solution.
  • Class-level variables can be problematic when multiple classes rely on them.
  • Singletons are often a better approach than statics.
  • Message bundles can be used for internationalization.
  • Constants classes can be used for enumeration, but ideally should be defined within each class.

Key Takeaways

  • Static values and methods can be problematic in object-oriented programming.
  • Class-level variables can lead to tight coupling and difficulty in extending or modifying the code.
  • Singletons and message bundles are often more effective alternatives to statics.
  • Constants classes should ideally be defined within each class rather than at the application level.
  • Internationalization can be achieved using message bundles.

Practical Lessons

  • Consider using singletons or message bundles instead of statics.
  • Define constants classes within each class rather than at the application level.

Strong Lines

  • Every rule has its exceptions.
  • Sometimes you need to break the rules to get the job done.

Blog Post Angles

  • The challenges and limitations of using statics in object-oriented programming.
  • Alternatives to statics, such as singletons and message bundles.
  • Best practices for using constants classes and message bundles.
  • How to achieve internationalization using message bundles.
  • The importance of flexibility and maintainability in software design.

Keywords

  • object-oriented programming
  • statics
  • singletons
  • message bundles
  • constants classes
  • internationalization
Transcript Text
This is Building Better Developers, the Develop-a-Noor 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're continuing our season where we're talking about object oriented programming from a practical sense. In this episode, we are going to look at statics. This would be static values, static methods, and they are, I think, supported everywhere. I'm trying to think of places where they're not. There probably are some languages that don't. But just to start off, generally speaking, a static is something that exists at the class level and not at the instance level. So if I have a car class and I have three different instances, I have my car, my spouse's car, my child's car, those three instances are going to have properties that are by instance. If I have something static, then that means that there's essentially a shared property or shared method up at the class level. The key thing about a static, a class level value, is that it's not going to be able to access instance things. So if you were to have a static method that tried to work on a property of an instance, it doesn't have access to that. The class doesn't know about the instance. The instance only knows about the class. So you have to watch out. What you do at the class level has to stay up there and it does have some limitations. Typically, if there's a value that's at a class level, then it's going to be like maybe an instance count. If you want to limit the number of instances of a specific class, particularly if you want to limit it to one, if you want to have a singleton, then you could have a class, an instance counter that once you instantiate a class that says, hey, I have an instance and so this is what I'm going to use. You may also have a reference to that instance to say once I have an instance, then there is a class level reference to it so I can always get to it. There are many, many other reasons that you may want to do statics. Static methods are really not, in a sense, they're not clean, I guess, unless they are dealing with static level variable, class level variables like the instance counter. You may have a, for example, you may have like a factory kind of thing where you would have a class level creator of an instance as opposed to instances somehow being created off the class itself. This allows you to do things like instance counting, maybe even have references to all of the instances of a given class. Some of those, there's definitely value for some of those things, but it also can complicate things to some extent because then you have to keep straight what's at the class level and what's down at the instance level. Static method sometimes also is used for global type functions and variables. A good example would be maybe like a converter. If you wanted to, let's say you had a string or let's say you had a number, some sort of a decimal number, and you wanted to be able to parse a string to be able to take a string and convert it into a decimal. You may want to do that as a static class, as a static method up at the class level. You just pass it in a string and it's going to kick out a decimal. However, more ideally, what you would have would be a decimal class and then it would have a constructor that takes a string and creates a decimal. This again is sometimes you're splitting hairs a little bit and you will find situations where there's something that really doesn't, it's a method that belongs on the class, but it doesn't actually deal with any of the properties of that class or actually of that instance. Then maybe it makes sense for it to be static. Sometimes there's going to be helper functions that it makes sense for those to be static because really they're not doing anything at an instance level. The challenge with that though is that anything that, if it's a static method, then unless it's a class level property, you have to pass in parameters for whatever you're going to be working on. There may be alerts, logging, and some things like that that are just, every instance is always going to call the same thing. It's always going to need essentially the same result, in which case, okay, it's static level. Other than those situations where you need to have a class level variable, that it doesn't make sense for it to be down on the instances. This usually is going to be some sort of instance management tool or set of functions and values. Then really you're cheating if you're doing stuff at a static level. This includes probably one of the more popular or famous approaches to statics is the idea of message bundles. That is typically what happens here is if you have something where you want to support or need to support internationalization. The strings that are displayed as part of your application actually need to be able to be done in multiple different languages. There are some programming languages that have built in support for message bundles. Usually what they do is they have a property file somewhere that the property file that's loaded is based on whatever your primary language is and it pulls that kind of stuff in. Some people do this a little bit differently. They also do this, and this really translates also to general messages, error messages and things like that. have this, we'll call it constants class, and all it is is statics. It's going to have all of these static values, basically these attributes. Typically essentially it's an enumeration. Let's say I've got 10 different errors that show up on my application. Well, I'll have a more user-friendly name for it than just a number. Instead of error code 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, I will have out of memory error, and I will have file unable to find file error, and system not available error, something like that. The names are more human readable, and it doesn't feel like there's a magic number or something like that. actually gives the developer a way to see what those numbers are. Now the challenge in doing that, while it makes sense and it's useful from an object-oriented point of view, if you do that up at the application level, then all of those classes that are in that application now have built in a sense a, you've essentially contrived a link between those classes. Even if they never actually use each other, because they use that shared resource of that constant, then there can be some issues with that. Ideally what you would do is you'd have those constants defined out within each class, so they don't have this reliance on that constant file that needs to be there. Later yet, what you have is you have those constants defined, or those enumerations defined at the class, and they could use a message lookup class that takes a value and then takes an integer, essentially kicks back a string. That is your more object-oriented approach. It allows each class to administer its messages and its errors to some extent, and it says these are the things that I need to support, and then I'm going to use this other helper to actually go figure out what that text is and what that string is that it's going to return. You see this, another good example is logging functionality. Now, technically, I could have a global static method that takes a string and then it prints it out or saves that out to a file. The challenge with that is that I probably have to send it a file name, or maybe there's a default file that I'm always going to use for my logging, but that's not very flexible. It's not very scalable. I may want to do something else. Instead, what I need to do is what we often see is there's essentially a logger class that handles that. We're going to talk about some specifics about these things as we get into constructors and destructors in the next couple episodes. What we want to do is we want to be able to leave the requirements and the definitions of those types of tasks to an instance as opposed to putting it up on a class level. Essentially, if we do it at the class level, that means that if we want to change it, if we want to extend it, then really we need to create a new class. There's other things out there that may be using that class, the existing class. If we start changing that static level stuff, that class level stuff, that means we have to change it. We are changing it for everything else that uses it. That puts us into some rough situations. I'm trying to just think of examples I've seen. It may be a list. There's a list of items. Again, it's much like that constant for messages. Maybe there's this list that we always want to get. It's an application level value, in which case, then what we need to do is have a way that we would have some sort of an application level, an application class, and then it would have instances. This would be a good example of having a singleton. We would have an application class. We would create an instance of it for our application. All the classes within our application would refer up to that application instance. Instead of having statics, ideally, we're going to end up actually having singletons. There are, again, like I said before, every rule has its exceptions. Sometimes you want to break the rules, particularly in the object-oriented world, because there is that cost to this abstraction. Sometimes we really need to remove a couple of layers of abstraction to make sure that stuff performs at the level that we need. That's the thought on statics. That is the challenge of the day, the challenge of the week, is take a look if you're using statics within your application, maybe even within your classes. Is that the right way to do it? Does it really make more sense, particularly from a global point of view, that instead you've got some sort of a class that you plug in, some sort of helper that provides that functionality? Obviously, there are going to be things. Like I said, again, at the class level, you may have class level error codes and stuff like that. Those make perfect sense, but particularly when you start getting into class level methods, maybe it would make more sense for there to be some sort of a helper class that you use or a singleton. That being said, I'm going to go out to your singleton of the day. You get it one time. Let's go out there and make the most of it. 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 North 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 developer.com. Just a step forward today is still progress, so let's keep moving forward together.