For Jet to be truly flexible, helpful, and non-intrusive, it must be possible to customize everything as you need it. It's not just possible to say: this is so and so, this is how it has to be and there's nothing you can do about it. This problem is solved in Jet in two ways.
The first frequently used method is dependency injection. Many parts of Jet work by having a facade - a container that serves as a unified interface, and injecting a backend (service provider) that already performs the actual activity - service. This is how the cache, translator, autoloader, even application module management, and many other things are handled. However, not everything can be handled this way.
The second option is used where Jet itself needs to create instances of some classes. Let's take Jet MVC as an example. Jet needs to create instances of bases, pages, as well as views and layouts. Or a system of application modules. The latter needs to instantiate module manifests. And so on.
And for these situations, it is necessary to somehow ensure that Jet does not create instances of a particular class directly. For example, when it needs to instantiate a page, it should never create an instance of Jet\MVC_Page directly, because this class must be interchangeable with a completely different class. Interchangeable, for example, with your class, which will add features to the system that it doesn't have in its base. So the class for the page doesn't necessarily have to be Jet\MVC_Page, but maybe JetApplication\MyMVC_Page. Of course, with the caveat that your JetApplication\MyMVC_Page class must always meet the conditions, usually implementing some interface, for example in this case Jet\MVC_Page_Interface.
And this whole situation is being solved by the factories. The purpose of the factories in Jet is:
- On demand, create instances of classes that perform a certain role (and thus have a certain interface).
- Carry information about the names of the classes that will be used for the purpose.
- Allow to change and set the names of the classes used.
Factories in practice
Let's show this in practice with an example. You want to use view. The first thing that comes to mind is to do this:
$view = new MVC_View('/somer/dir/');
But then it turns out that you need a custom view in your project that can do something that Jet\MVC_View can't. What to do with it? Are you going to change the class name everywhere in the sources, including the Jet library? Or will you use different spells? No. It's best to use factories consistently. I mean, create a view like this:
$view = Factory_MVC::getViewInstance('/some/dir/');
Yes, it's a few extra letters, but it won't kill anyone :-)
And when you need a custom implementation of view (even if it is compatible with the old one in terms of the basic interface), this is what you do in your application initialization:
Factory_MVC::setViewClassName( MyView::class );
Immediately part of the system is your improved view implementation. It is available everywhere, in modules, controllers and so on. Simply, transparently and without magic.
Note: If you look carefully at the installer source code, you will see that view is "cheerfully" used there without the factory. This is not a bug, but the intention. There is a logic to it. Things like the installer, or Jet Studio, are largely independent applications, separate from the actual final application to be developed on Jet - thus it stands outside your project. That's why, for example, for the installer and Jet Studio, it needs the View implementation it knows - that is, the one from Jet. However, within the application and application space itself, using factories is more than appropriate. Don't be fooled into thinking that the bundled tools don't follow this concept.
List of factories
|Jet\Factory_Application||Factory focused on working with application modules.|
|Jet\Factory_DataModel||Factory designed for ORM DataModel.|
|Jet\Factory_Db||Factory for working with the backend connecting to the database.|
|Jet\Factory_Form||Factory designed for the forms subsystem.|
|Jet\Factory_MVC||Factory for Jet MVC.|
|Jet\Factory_PackageCreator||Factory for CSS and JS packager.|
|Jet\Factory_Translator||Factory designed for translator.|
|Jet\Factory_Config||Factory for configuration system.|