# Dependency inversion principle and WordPress

So let's talk about [coupling](https://carlalexander.ca/coupling-cohesion-wordpress/)! Coupling is a complicated problem because you can never get rid of it completely. All that you can do is control how much it spreads. And there's more than one way to do that. One of these ways is the [dependency inversion principle](https://en.wikipedia.org/wiki/Dependency_inversion_principle). It's one of the most important principles in [object-oriented design](https://en.wikipedia.org/wiki/Object-oriented_design). And it's why it's part of the famous [SOLID](http://en.wikipedia.org/wiki/Solid_(object-oriented_design)) design principles. (It's the "D" in SOLID.) The dependency inversion principle isn't something that you see with WordPress. That's because most WordPress developers don't use object-oriented programming. (But it's always a [good time to start](https://carlalexander.ca/object-oriented-programming-next-step-wordpress-developer/) if you're not using it!) And the dependency inversion principle only helps when you've been using it for a while. But what makes the dependency inversion principle special? Why is it such almost a mandatory aspect of object-oriented design? These are good questions that you deserve an answer to.

# What is the dependency inversion principle?

[Robert C. Martin](https://en.wikipedia.org/wiki/Robert_C._Martin) (also known as Uncle Bob) created the dependency inversion principle. He's a famous software engineer who's contributed a lot to the field of [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming). For example, all the principles in SOLID are his. (He's famous for this and his contribution to the [Agile Manifesto](https://en.wikipedia.org/wiki/Agile_software_development#The_Agile_Manifesto).) As we said in the introduction, the goal of the dependency inversion principle is to reduce coupling in your code. The principle works by reversing (that's why it's called inversion!) the dependency relationship between your classes. It states that: > A. High-level modules should not depend on low-level modules. Both should depend on abstractions. B. Abstractions should not depend on details. Details should depend on abstractions.

This is a pretty intimidating set of statements. What do we mean by module, abstraction and details!? These aren't words that you're used to seeing with object-oriented programming. It's ok if this doesn't quite make sense yet. (That's why you're reading this article!) We're going to go through each of these statements to see what they mean. But first, let's talk about the typical way that you use classes together. # A conventional object-oriented plugin

To better understand the dependency inversion principle, you have to look at how you use classes together without it. Let's imagine that we have a small object-oriented plugin. Here are some of the classes that we created for it: ```
class MyPlugin_Plugin
{
    /**
     * MyPlugin admin page
     * 
     * @var MyPlugin_AdminPage
     */
    private $admin_page;
    
    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->admin_page = new MyPlugin_AdminPage();
    }

    // ...
}

class MyPlugin_AdminPage
{
    /**
     * MyPlugin options
     *
     * @var MyPlugin_Options
     */
    private $options;
    
    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->options = new MyPlugin_Options();
    }

    // ...
}

class MyPlugin_Options
{
    /**
     * MyPlugin options
     * 
     * @var array
     */
    private $options;

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->options = array();
    }

    // ...
}
```

We have three classes in the code sample above. We have the `MyPlugin_Plugin` class with a constructor. This constructor creates an instance of the `MyPlugin_AdminPage` class. Then we have the `MyPlugin_AdminPage` class. It also has a constructor like the `MyPlugin_Plugin` class. But the difference is that it creates an instance of the `MyPlugin_Options` class. The last class is the `MyPlugin_Options` class. It's also the simplest. It only uses an internal `options` array. Like our two other classes, we initialize the array in the constructor. ## Dependencies between our classes

Now, let's look at how these three classes depend on each other. This isn't too hard to deduce based on our earlier description of the code. Using this information, let's create a diagram describing the dependencies between our classes: ![](https://carlalexander.ca/wp-content/uploads/2017/04/plugin-dependencies-diagram.png)As you can see, the `MyPlugin_Plugin` class depends on the `MyPlugin_AdminPage` class. And the `MyPlugin_AdminPage` class depends on the `MyPlugin_Options` class. Meanwhile, the `MyPlugin_Options` class has no dependencies. But we also ordered these classes from highest to lowest. The `MyPlugin_Plugin` class is the highest while the `MyPlugin_Options` class is the lowest. This lets us explain one of the two statements in the dependency inversion principle. > High-level modules should not depend on low-level modules. Both should depend on abstractions.

It's worth clarifying now that, for us, the term "module" really means "class". This means that, according to the dependency inversion principle, our three classes have a problem. They shouldn't depend on each other like they do right now. Instead, they should depend on abstractions. ## Depending on interfaces

But what does abstraction mean in the context of the dependency inversion principle? It often just means an [interface](https://carlalexander.ca/polymorphism-wordpress-interfaces/). Instead of depending on each other, our three classes should depend on interfaces. This is where the idea of inversion comes from. It's not about reversing the order of the coupling between our classes. We're not looking to have the `MyPlugin_Options` class depend on the `MyPlugin_AdminPage` class and so on. (That'd be weird!) No, it's about depending on an interface instead of a concrete class. The inversion is between class and the interfaces that it implements. We're coupling ourselves to one of these interfaces instead of the class itself. That's the fundamental idea behind the dependency inversion principle. You want your classes to depend on interfaces and not other classes. This isn't possible in our example because it doesn't use interfaces. # Adding interfaces

So let's rectify this issue and create interfaces for the classes in our example. We're going to do this from the bottom up. That means starting with the class with no dependencies and moving up from there. ```
interface MyPlugin_OptionsInterface
{
    /**
     * Gets the option for the given name. Returns the default value if 
     * the value does not exist.
     *
     * @param string $name
     * @param mixed  $default
     *
     * @return mixed
     */
    public function get($name, $default = null);

    /**
     * Sets an option.
     *
     * @param string $name
     * @param mixed  $value
     */
    public function set($name, $value);
}
```

So here's our `MyPlugin_OptionsInterface` interface. It's a small interface with two methods: `get` and `set`. These two methods let us interact with our plugin options. Now, we need to update our `MyPlugin_Options` class. We want it to implement the `MyPlugin_OptionsInterface` interface that we just created. You can find the updated class below: ```
class MyPlugin_Options implements MyPlugin_OptionsInterface
{
    /**
     * MyPlugin options
     *
     * @var array
     */
    private $options;

    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->options = array();
    }

    /**
     * {@inheritdoc}
     */
    public function get($name, $default = null)
    {
        return isset($this->options[$name]) ? $this->options[$name] : $default;
    }

    /**
     * {@inheritdoc}
     */
    public function set($name, $value)
    {
        $this->options[$name] = $value;
    }

    // ...
}
```

As you can see, the `MyPlugin_Options` class hasn't changed too much. We only added the two methods defined in the `MyPlugin_OptionsInterface` interface. The `get` method uses a [ternary operator](https://secure.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary) to return the value in the `options` array if it's set. Meanwhile, the `set` method inserts the `value` parameter in the `options` array using the `name` parameter as the key. ## Reworking our constructors

Now, that we have the `MyPlugin_OptionsInterface` interface for the `MyPlugin_Options` class. We can update our `MyPlugin_AdminPage` class to use the interface instead of the class. This is going to require that we rework the `MyPlugin_AdminPage` constructor: ```
class MyPlugin_AdminPage
{
    /**
     * MyPlugin options
     *
     * @var MyPlugin_OptionsInterface
     */
    private $options;

    /**
     * Constructor.
     */
    public function __construct(MyPlugin_OptionsInterface $options)
    {
        $this->options = $options;
    }

    // ...
}
```

When using an interface, we can't create a `MyPlugin_Options` object in the constructor like we did earlier. We need to pass the object implementing the `MyPlugin_OptionsInterface` interface as an argument. We then assign the object to the internal `options` variable. # We don't want to care about the details

So why is this better? Why couldn't we just pass a `MyPlugin_Options` object as an argument? Why is the interface better? The answer lies in the second statement of the dependency inversion principle. > Abstractions should not depend on details. Details should depend on abstractions.

So, as we know from earlier, abstractions are our interfaces. But what does it mean by details? It means what's going on inside our classes. The statement is a warning meant to prevent us from creating another type of dependency. This time it would be between our classes and interfaces. We shouldn't design an interface based on the needs of our class like we just did with the `MyPlugin_OptionsInterface` interface. Instead, it's the interface that should dictate what the class should do. And then it's up to the class to figure out how to do it. The implementation "details" shouldn't matter to the interface. That's why the contract analogy is so good with interfaces. When a class implements an interface, we don't care how it does things. All that we care about is that it satisfies the interface's contract. # Creating the proper abstractions

Because of this second statement, creating an interface isn't a simple task. We can't just create a generic interface that mirrors the methods found in our class and call it a day. (If only it were that easy!) Such an interface won't reduce coupling in any meaningful way. A better way to reduce coupling is to design our interfaces based on the needs of the class that'll use it. But didn't we just say that we shouldn't do that? Not quite! There's a subtle difference. ## Designing an interface for admin pages

The best way to highlight this difference is by using an example. Let's design an interface for our `MyPlugin_AdminPage` class. But this time, we'll use the needs of the `MyPlugin_Plugin` class to do it. ### The needs of our plugin class

So what does the `MyPlugin_Plugin` class need from the `MyPlugin_AdminPage` class? Well, it could want a way to register an admin page with WordPress. So we could have something like this: ```
class MyPlugin_Plugin
{
    /**
     * MyPlugin admin page
     *
     * @var MyPlugin_AdminPageInterface
     */
    private $admin_page;

    /**
     * Constructor.
     */
    public function __construct(MyPlugin_AdminPageInterface $admin_page)
    {
        $this->admin_page = $admin_page;
    }

    /**
     * Loads the plugin into WordPress.
     */
    public function load()
    {
        $this->admin_page->register();
    }

    // ...
}
$myplugin = new MyPlugin_Plugin($admin_page);
add_action('wp_loaded', array($myplugin, 'load'));
```

We made two important changes to the `MyPlugin_Plugin` class. First, we modified its constructor. It now wants an object implementing the `MyPlugin_AdminPageInterface` interface as an argument. Above that `MyPlugin_AdminPageInterface` object is represented by the `admin_page` variable. We still assign that object to the `admin_page` internal variable. Next, we added a new method called `load`. It's a method that we hooked to the [`wp_loaded`](https://codex.wordpress.org/Plugin_API/Action_Reference/wp_loaded) hook. We picked this hook because it's the last hook of the [WordPress loading process](https://carlalexander.ca/wordpress-adventurous-loading/). Meanwhile, the `load` method itself only does one thing. It calls a `register` method of the object stored in the `admin_page` internal variable. This `register` method is what the `MyPlugin_Plugin` class needs from the `MyPlugin_AdminPageInterface` interface. ### An interface to meet these needs

Using this knowledge, we can design the `MyPlugin_AdminPageInterface` interface. The goal for it is to solve the problem that we highlighted in the `MyPlugin_Plugin` class. Here's what it would look like based on what we know: ```
interface MyPlugin_AdminPageInterface
{
    /**
     * Register the admin page with WordPress when WordPress loads.
     */
    public function register();
}
```

We know that the interface needs a method called `register`. Its job is to register the WordPress admin page. We also specify in the method description that this happens when WordPress loads. That's because we can't have any code in an interface. So we need to be thoughtful documenting our method. We need enough information so that the class can implement the "details" in the correct way. ### Implementing the details

Now that we have our abstraction, we can look at implementing the details in the `MyPlugin_AdminPage` class. We know from the interface that we need a `register` method. So let's add it: ```
class MyPlugin_AdminPage implements MyPlugin_AdminPageInterface
{
    // ...

    /**
     * Register the admin page with WordPress when WordPress loads.
     */
    public function register()
    {
    }

    // ...
}
```

Let's leave the method empty for now so that we can think about the implementation details. First, we need to add the admin page. We do that using the [`add_menu_page`](https://developer.wordpress.org/reference/functions/add_menu_page/) function. ```
class MyPlugin_AdminPage implements MyPlugin_AdminPageInterface
{
    // ...

    /**
     * Display plugin admin page.
     */
    public function display_page()
    {
        // ...
    }

    /**
     * Register the admin page with WordPress when WordPress loads.
     */
    public function register()
    {
        add_menu_page('My Plugin Admin Page', 'My Plugin Admin Page', 'edit_posts', 'myplugin_admin_page', array($this, 'display_page'));
    }

    // ...
}
```

Adding the call to `add_menu_page` function like we did above works if you're in the WordPress admin. Whenever you navigate to your plugin's admin page, WordPress will call the `display_page` method. That said, the`register` method will generate an error when you're not in the WordPress admin. So we need to add an extra layer to control when we call the `add_admin_menu` function. ```
class MyPlugin_AdminPage implements MyPlugin_AdminPageInterface
{
    // ...

    /**
     * Add admin page to WordPress admin menu.
     */
    public function add_page()
    {
        add_menu_page('My Plugin Admin Page', 'My Plugin Admin Page', 'edit_posts', 'myplugin_admin_page', array($this, 'display_page'));
    }

    /**
     * Display plugin admin page.
     */
    public function display_page()
    {
        // ...
    }

    /**
     * Register the admin page with WordPress when WordPress loads.
     */
    public function register()
    {
        add_action('admin_menu', array($this, 'add_page'));
    }

    // ...
}
```

So here's the extra layer needed to add our menu page without any errors. We added a new method called `add_page` where we put our call to `add_menu_page`. We then hooked the method to the `admin_menu` hook which is the recommended hook to use in the codex. ## On abstractions and details

This problem with the `add_menu_page` function is important. We could redesign the `MyPlugin_Plugin` class with this problem in mind. (But that's a decision that you have to make.) For example, we could call the `register` method from the `admin_menu` hook. That said, we didn't design our `MyPlugin_Plugin` class that way. And the class implementing the `MyPlugin_AdminPageInterface` interface needs to deal with that reality. That's what we mean when we say that abstractions shouldn't depend on details. ![](https://carlalexander.ca/wp-content/uploads/2017/04/dependency-details-diagram.png)This diagram above is another way to look at this relationship between abstractions and details. If the `MyPlugin_Plugin` class is part of a layer, the `MyPlugin_AdminPageInterface` interface would be part of that same layer. We design both at the same time. Meanwhile, the `MyPlugin_AdminPage` class lies on a layer below the `MyPlugin_Plugin` class. It implements the `MyPlugin_AdminPageInterface` interface from the above layer. But, by being on different layers, we don't have to design the two at the same time. This is also why it's a bad idea to create a generic interface based on a class. From a layer perspective, the `MyPlugin_AdminPage` class shouldn't dictate the inner workings of the `MyPlugin_Plugin` class. It needs to be the other way around. ## Always use an abstraction

Now, if we look back to our `MyPlugin_Options` class and its interface, it doesn't quite fit the layers model that we have so far. It would feel weird from the layer containing the `MyPlugin_AdminPage` class to also contain the interface for the `MyPlugin_Options` class. In practice, you'll use the `MyPlugin_Options` class in a lot of different layers. Why do we need an interface for the `MyPlugin_Options` class then? The reason for it is that a class should never depend on a concrete class. It should always depend on abstractions. That's because an interface always creates less coupling than a concrete class. This is true even for a generic interface. That's why it's ok to create a generic interface like the `MyPlugin_OptionsInterface` interface here. # The big picture

So here we are! We've reworked our plugin classes using the dependency inversion principle. The result is classes that are less coupled to one another. ![](https://carlalexander.ca/wp-content/uploads/2017/04/final-plugin-dependencies-diagram.png)And here's our final class dependency diagram. It illustrates how our modified classes, as well as our new interfaces, depend on one another. It's not as simple as our original one so let's walk through it. We still have three layers like we had in our original diagram. That said, the flow of dependencies changed. It doesn't all go from top to bottom anymore. The `MyPlugin_Plugin` class depends on the `MyPlugin_AdminPageInterface` interface. Both of the `MyPlugin_Plugin` class and the `MyPlugin_AdminPageInterface` interface are on the same layer. This is the direct result of our use of dependency inversion. We reduced the coupling in the `MyPlugin_Plugin` class by not making it depend on another layer. That said, the dependency inversion principle doesn't work all the time. The `MyPlugin_AdminPage` class still depends on the `MyPlugin_OptionsInterface` interface which is on the layer below it. But we still reduced the coupling by switching our dependency to the `MyPlugin_OptionsInterface` interface. # It's a question of scale

So that's the dependency inversion principle! It might look like a lot of work for almost no benefit. (There's a good chance you might feel that the code is way more complicated as a result.) But that's just because our example was so small. With object-oriented programming, you can have dozens, hundreds or even thousands (gasp!) of classes. Coupling is a real issue when working at that scale. And that's also where the dependency inversion principle comes into its own. But you shouldn't wait until your code reaches that scale to start practicing it. In fact, it's better to get used to it as early as possible. This will allow you to design classes that won't always break as your code grows.