Compatibility and Flexibility of New Features and Refactoring of Old Ones

When writing logic that is used in different modules, especially when these modules exist in separate submodules of a repository, it is very easy to encounter a Fatal Error that can crash an entire project. These kinds of tasks should always be handled carefully, considering that changes to modules might be merged or deployed in parts. It is crucial to evaluate and monitor the fault tolerance of the code.

Let's analyze in detail how to properly approach this, using an example of adding logo display logic for themes.

Task

Move the logo display logic into a method so that it can handle different ways of forming the logo path, include options to enable/disable it, and more.

Problem

A new method, fetchLogo, was created in JimboPlugin but was not added to ISystemPlugin. Additionally, changes were accepted in SmartAdmin but not in JimboPlugin.

As a result, when the project or development branch was updated, it caused a Fatal Error, requiring either waiting for the necessary fixes or temporarily commenting out the logo display code in the template.

Solution

How could this have been avoided? A straightforward solution:

if (is_callable(array($systemPlugin, 'fetchLogo'))) {
    echo $systemPlugin->fetchLogo($info);
}

This approach is not ideal, but it would have prevented the project from crashing.

Better Approaches:

  1. Implement ITheme in the System Plugin. Modify JimboPlugin to implement ITheme, allowing the template to check for compatibility before calling the method:

    if ($systemPlugin instanceof ITheme) {
       echo $systemPlugin->fetchLogo($info);
    }

  2. Modify DisplayPlugin to retrieve an instance of a class implementing ITheme. This allows templates to use:

    echo $this->getTheme()->fetchLogo();
    In this approach, there is no need to pass the info array explicitly, as it will already be available inside the ITheme class.

  3. Initialize ITheme in the display method of DisplayPlugin and pass it to the global template:

public function display($content, $template = 'main.phtml')
{
   ...
   $this->theme = new Theme($info);
   ....
}

Then, in the template, simply call:

if (isset($theme)) {
   echo $theme->fetchLogo();
}

Comparison of Solutions

  • Approach #1 and Approach #3 have a higher reliability than Approach #2, reducing the risk of a Fatal Error.
  • Drawback of Approach #1: JimboPlugin is already overloaded with methods and logic, making it necessary to refactor. Adding another method would not be the best choice.
  • Given the above considerations and SOLID principles, Approach #3 is the most appropriate solution at this stage.

There are even better solutions, but implementing them would require more time and effort.