In this series, we're taking a look at design patterns and how we can leverage them to our advantage when building products on top of WordPress.
The nice thing about design patterns is that they aren't explicitly limited to themes or plugins - they are handy in a variety of different scenarios. It's simply a matter of being able to identify which patterns are applicable to certain scenarios.
In the last post, we reviewed the Singleton Pattern. In this article, we're going to take a look at the Simple Factory Pattern which is especially useful when you have a number of different classes each of which has a unique purpose and solves a specific problem.
In this post, we'll take a look at another pattern - the Simple Factory Pattern - which is useful when you have a number of classes each of which has a unique purpose and that can be selected based on certain criteria.
The Factory Method Pattern
The Simple Factory Pattern is actually derived from a pattern known as the Factory Method Pattern which is a slightly more complicated version of the pattern that we're going to be reviewing.
According to Wikipedia, the Factory Method pattern is defined as follows:
The factory method pattern is an object-oriented creational design pattern to implement the concept of factories and deals with the problem of creating objects (products) without specifying the exact class of object that will be created
Sounds a bit complicated, doesn't it?
The truth is, it's actually a really powerful design pattern but it would take a much longer article to discuss it, and it's a bit out of scope for the purpose of this series.
So, as mentioned, we're going to take a look at a version of the pattern that's paired down a little bit and should be more generally applicable to less complicated projects.
Before we do that, let's come up with a definition of the Simple Factory Pattern:
The Simple Factory pattern returns a specific set of data or a specific class based on its input.
Ah the risk of making a pun, simple, right?
A Note About the Simple Factory Pattern
The truth is, many software engineers refer to the Simple Factory more as an idiom than a full-blown pattern; others consider this a pattern.
For what it's worth, I see it as a very simple pattern. It has a specific use case that can be easily identified when to use it during the course of development which we'll review later in this article.
Regardless, I bring this up so that if you see this used as an idiom (or a pattern) used throughout various articles on the Internet, or even in conversation, you'll know that the developers in question are referring to the same programming strategy - just in a different way.
So Why Does This Matter in WordPress?
Just as design patterns in non-WordPress specific projects, such as larger applications, the design patterns provide a tried and true way to solve a common problem.
It helps to abstract our code a bit, keep our project easily maintainable, easily readable, and can actually help us to keep our code lean. This may result in us actually having more files in our project, but each file should have fewer lines of code.
This means that each file should have a specific purpose that should be clear, not only to us, but future developers as well.
What It Looks Like
Now, before we dive into the diagrams, talking about classes, and the strategies required to implement the actual pattern, I want to mention that we're going to be taking a simple approach to this.
The thing is, the readership of this blog spans a wide array of experiences - we have some people who are learning to write code; others who are seasoned veterans.
In order to appeal to the majority of the readership, we need to strike a balance. So for those of you who have been involved with software engineering for years, this may seem overly simplistic; however, don't skim it - perhaps you'll pick up something new.
For those of you who are beginners or even intermediate programmers, pay close attention to what we're discussing as it can provide dividends in future (or even existing) work.
The Purpose of the Simple Factory
So imagine this scenario: You're working on a function that takes in a set of input - usually some type of unique string or integer - and you have this long if/else
statement or perhaps you have this large switch/case
statement that continues to grow as your project grows.
The problem is that the conditionals become a pain to manage. In fact case conditionals, or the case blocks, may actually end up doing as much work as a certain function should do.
This is where the Simple Factory comes into play. What we can do is abstract the details happening in each of the conditionals into their own class thus making it much easier to maintain and keeping the code much leaner.
And that is the Simple Factory Pattern.
A Look at the Pattern
So here are the key features of the Simple Factory Pattern:
- Notice that the Plugin class has a private reference to the Factory class
- The Factory class encapsulates all of the logic to return an object of the type User
- The User class is a base class for three other classes: Admin, Volunteer, Reader, and the idea is that each of these types are subclasses of users with unique functionality of their own
- The Plugin will receive a certain type of input that it will pass to the Factory
- The Factory will examine the input and then, based on its value, will return one of the three user types
Nothing too complicated, right? Honestly, I think that the diagram is a bit more complicated than the principles at play. It really provides a lot of flexibility especially whenever you're looking to introduce another User type like an Editor or something similar.
Note: This is not to be confused with WordPress' built-in user types. This is simply an example to show what the pattern would look like.
A Working Example
Now that we've taken a look at the diagram for the pattern, let's take a look at the source code in action. Below, we'll look at the source code for each class and then I'll provide a download to a fully documented demo after the discussion.
The Plugin
First, let's look at the plugin class. Remember, this is nothing more than a prototype of what the pattern looks like. It's not the same thing as a fully developed WordPress plugin.
<?php include_once( 'simple-factory.php' ); class Plugin { private $factory; public function __construct() { $this->factory = new Simple_Factory(); } public function get_user( $permission ) { return $this->factory->get_user( $permission ); } } ?>
Notice that the plugin is relatively simple:
- It includes the simple-factory.php script in the header of the file
- It then defines a constructor in which it sets the
$factory
property to an instance of theSimple_Factory
- The only method available in the plugin is
get_user
which returns a user based on a type
We'll see how this comes into play after we've examined all of the other classes.
The User
The User
is an abstract base class that provides a basic constructor and an abstract function that must be implemented by all other subclasses.
<?php abstract class User { private $role; public function __construct( $role ) { $this->role = $role; } abstract public function get_role(); } ?>
Note that this class is intended to be subclassed by a variety of other classes, each of which we'll look at in detail momentarily.
The Administrator, The Reader, and The Volunteer
The following four classes are all separate files each of which subclass the User
base class. I've opted to include them all here together because there's so little deviation from their actual implementation that it should be easy enough to follow.
The Administrator
<?php class Admin extends User { public function __construct() { $this->role = "Administrator"; } public function get_role() { return $this->role; } } ?>
The Reader
<?php class Reader extends User { public function __construct() { $this->role = "Reader"; } public function get_role() { return $this->role; } } ?>
The Volunteer
<?php class Volunteer extends User { public function __construct() { $this->role = "Volunteer"; } public function get_role() { return $this->role; } } ?>
As usual, leave me questions in the comments; otherwise, review the code then be sure to read up on The Simple Factory which is the next section - it ties all of this together.
Also, remember that all of this code will be shared at the end of the article along with code comments that describe exactly what's happening.
The Simple Factory
The Simple_Factory
class is really the crux of the entire pattern. Here is where all the decisions are made and the appropriate objects are returned.
<?php include_once( 'users/user.php' ); include_once( 'users/admin.php' ); include_once( 'users/volunteer.php' ); include_once( 'users/reader.php' ); class Simple_Factory { public function get_user( $permission ) { switch( strtolower( $permission ) ) { case 'read-write': $user = new Admin(); break; case 'help': $user = new Volunteer(); break; case 'read': $user = new Reader(); break; default: $user = null; break; } return $user; } } ?>
Note that the Simple_Factory
includes the base user class and its subclasses and then works to return the appropriate type of user based on the incoming set of permissions.
The Advantages of the Simple Factory Pattern
Though it should be a bit obvious by this point in the article, the Simple Factory Pattern provides a number of advantages especially if you're used to working with large conditionals.
- It provides an elegant way to abstract your code so there's less visual clutter
- It allows you to introduce specialized, focused classes with a single purpose (which is great if you follow the SOLID principles)
- It makes the code more maintainable as there's a single place where classes are instantiated, and each class serves a single purpose
Overall, this is one of my favorite patterns simply for the matter of code organization and specialization that it can bring to the table.
Conclusion
Finally, you can checkout the entire source code - complete with documentation and installation instructions - on GitHub using this link.
At this point, we've taken a look at three patterns:
- The Observer Pattern
- The Singleton Pattern
- The Simple Factory Pattern
This series could go one for a while; however, I think that we've covered enough ground at least to get many of us started with implementing patterns into our work.
So in the last article in the series, we'll recap what we've learned and I'll also recommend some other patterns, their purpose, and some further points of research that should continue to aid you in continuing to learn about design patterns and their advantages not only in WordPress development, but general software development, as well.
Comments