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:
-
Implement
ITheme
in the System Plugin. ModifyJimboPlugin
to implementITheme
, allowing the template to check for compatibility before calling the method:if ($systemPlugin instanceof ITheme) { echo $systemPlugin->fetchLogo($info); }
-
Modify
DisplayPlugin
to retrieve an instance of a class implementingITheme
. This allows templates to use:
In this approach, there is no need to pass theecho $this->getTheme()->fetchLogo();
info
array explicitly, as it will already be available inside theITheme
class. -
Initialize
ITheme
in thedisplay
method ofDisplayPlugin
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.