In the previous post, I started walking through the process of taking the idea for a plugin that rapidly prototyping it into something that works within WordPress. And though it works, it doesn’t necessarily follow any object-oriented principles, nor is it in a place that we can easily continue to add features.
No, this isn’t an argument for why object-orientation is better. It happens to be my preferred way of writing code so I’m approaching it this way.
I know that the example code I’m giving is simple and I know that a case can be made that something like this can be left as it is. But the point of this is to show how to take a concept, prototype it, and then move it into something that follows object-oriented principles.
And, in my experience, it’s much harder to do that with a complex example from the outset. if you lose readers from the beginning, then what hope is there for them to understand what’s coming?
So with that said, we’re going to take a look at the code from the previous post and do a bit of a concept analysis on it to see what might work well within a class and how we might begin to organize it using classes, namespaces, and so on.
Whenever it comes to programming, it’s so easy to want to jump into immediately writing code and then wrangling it into submission until it does something that we want.
And once it works, it feels like we’re done and we can move on to the next task. But for larger projects, that’s not always the case. In fact, it’s often better to do a bit of concept analysis of object-oriented analysis on your design before moving forward.
Simply jumping into coding isn’t always the best approach.
A Case For Analysis
Case in point: At the time of this writing, one of my teammates and I are having a discussion on if we should extend a class or write a new class to handle geolocation information for data pulled from the Google Maps API.
Can I wing it and write something that works? Sure. But will it integrate well with the application? Not without concept analysis, planning, and coordinating with the rest of the system.
And that’s what the purpose of the analysis is all about.
Analyzing Our Work
So what does this mean for the plugin we looked at yesterday? Right now, we have the following:
- a function responsible for creating a meta box and displaying the contents within it,
- a function for querying the database and retrieving the last most recent posts,
- a function for displaying the results in the meta box
- a function for displaying a message when there are no results in the meta box
Further, a number of these functions are related to hooks that are part of the WordPress API. Namely, the function for creating the meta box is hooked to WordPress and its companion function for rendering the display are all part of the same component.
Then we have functionality for querying the database and we have functions directly related to views.
So how might this look if we were to diagram this out into various classes and files that would help to create this in an more object-oriented manner?
No Single Solution
There’s no single solution and some solutions are far more advanced than others. But since I’m trying to strike a balance here, I’m going to approach this in a simpler way than doing too much work with abstraction, inheritance, interfaces and all of that.
Focusing on What We Have
For now, let’s focus on individual classes and the responsibilities they may hold. For example:
- I think we’re going to need a class that represents the meta box. This should be responsible for creating the meta box.
- We’ll also need a class responsible for displaying the contents of the meta box. You may think that including a function in the class for the meta box works well. It does; however, if you want to think about each class as having a single responsibility, then we can create a class specifically for the display and specifically for the meta box, then inject the display into the meta box during instantiation. We’ll talk more about this later.
At this point, our diagram might look something like this:
Next, we need to consider the other functionality. Namely, the functionality for displaying the results in the meta box and the functionality for displaying the results when there are none.
In order to display anything in the meta box, we need to have a way to query the database to retrieve the results. From there, we then need to be able to have a way to determine if there are results, if there aren’t and then inject those results into the view.
Given this information, it sounds like we need a class for querying the database and then we need a class to broad a message into the display of the meta box.
Perhaps one way to organize the classes would look like this:
The final version of the diagram may be a little cramped but we’re ultimately looking at something like this:
For the purposes of explanation:
- The post retriever asks the database for the last three most recent posts.
- The post messenger will determine which message to inject to the display.
- The display will render the message that’s been set.
- The meta box will render its display to the web browser.
So we’ve essentially taken a few functions that were hooked into WordPress and broken them down into components than can communicate with one another each of which are relatively easy to work with and don’t do more than a single job.
Converting It To Code
Now that we have an idea as to how we can convert the previous concept into code, we’ll look at how to do that in the next couple of articles.
Note that how you opt to implement your code or design your classes may be a little different than what I have above and you may have suggestions on how to better organize what’s above. If that’s the case, leave a comment.
In the next post, we’ll look at converting this into functional code and, after that, we’ll look at organizing this into proper namespaces and proper file organization.
- Rapid Prototyping with WordPress: From Concept To Plugin
- Rapid Prototyping with WordPress: Concept Analysis
- Rapid Prototyping: Prototype To Code, Part 1
- Rapid Prototyping: Prototype To Code, Part 2
- Rapid Prototyping: Introducing Autoloading