The idea of using some type of configuration files for a project isn’t anything new. Nor is the idea of using a format such as JSON.
Look in any directory for a number of major applications that you use, be it a source control manager, IDE, a build tool, et al., and you’re likely to find some type of configuration file. (And when it comes to build tools, many of us already write configuration files using JSON specifically to tell the build tool information about our project.)
Yesterday, I shared some of the challenges that can come with creatively solving problems and said that I was going to talk about something I’ve been working on:
With all of that said, it wouldn’t be particularly honest of me if I didn’t discuss and share my code, though, would it?
So that’s the purpose of this post: To talk about one way that I’ve been looking to solve a problem in a project on which I’m working.
Configuration Files Aren’t New (I Know)
To be clear, there are a few things that I want to address before tackling this particular subject:
- The idea of using a configuration file for a project or piece of software isn’t new.
- Sometimes, the reason some strategies aren’t used in programming is because they are known to be inherently complex or simply bad. If you find yourself in a position where you think you’re solving a problem creatively and others are telling you it’s an anti-pattern or that it’s not a good solution because of [several reasons], then they may be right.
I think it’s important to mention those two points; otherwise, it may come off as if I think any type of configuration file is a new idea. 🙄
Some like to jump to the comments at the first point they see with which they disagree (don’t be that person 🙂), so it’s important to give context to a given problem.
And with that out of the way, let’s actually talk about code.
1. Rationale for Configuration Files
The idea behind using configuration files for class instantiation comes into play whenever you have a number of classes in a project that has properties that may:
- frequently change,
- require some type of information the developer can’t know during development time,
- depend on third-party data,
I think you can make a case that this also comes into play whenever you’re testing your code, as well. It’s not a full-on process of mocking a class, but you are able to easily provide sample data.
The idea behind this works is simple (implementation may seem more complex to some more than others):
- You have a class (or a number of classes, really) in your project each of which maintains a set of properties.
- These properties are set in the constructor of the class. How they are set – be it through constructor arguments, some type of injection, or whatever – doesn’t matter.
- The implementation would ideally work with autoloading (which I’ll discuss later) but is suited for manually doing it, as well.
- Should be as decoupled from the native language as possible (at least in some cases).
To the last point: if you’re just using PHP then I think you could make a case that an array might do just as well. Or if you’re writing a binary, then maybe JSON or XML would work, too.
The data structure that you opt to use is secondary to how easy it is for someone else to work with it and for a program to parse. A balance that’s always fun to strike.
2. File Structure
For the purposes of this example, I’m going to be using JSON since it seems to be relatively popular among open source web applications as well as binaries regardless of the platform.
I want to keep the example short, so I’ll demonstrate using three classes, but the idea is that it can scale to however many classes are in the project.
First, here’s an example of setting up a generic class with a single property:
And here’s how a more complete example might look:
You can see the above code with a complete description of how it works in this gist.
Obviously, this is code just to demonstrate the point and it’s meant to be general enough that the implementation is the focus (rather than whatever the relationship the classes have with each other).
In other words, it’s meant to be simple. It needs more modification for strict languages and could be modified differently for dynamic languages.
But the idea is that, at runtime (or compile time or whatever ‘time’ your language of choice calls it :), the class is instantiated and then dynamically populated with its properties based on the data in the configuration file.
About That Class Instantiation Thing…
I originally wrote a longer section on class instantiation but it seemed a little pointless given that the article is more about configuration files than anything else.
But I think some of it still warrants mentioning especially around the process of class instantiation and autoloading. Specifically, we know that the process of instantiation can be handled via PHP.
We can do this manually or with an autoloader. And since I’m talking about configuring all the things with some level of dynamics, why not automate more of the process?
This ultimately allows us to focus on file organization and code without having to return to some other place to write an include statement and pass or declare a bunch of properties.
And that’s the admittedly generic example I have to share. It’s not something I can give a concrete example for because I’m working with more dynamic languages (and you may be working with a less dynamic language).