Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I am the owner and mantainer of the <a href="http://alloyframework.org" rel="noreferrer">Alloy HMVC Framework</a>, and I chose to have a core "Kernel" object as you describe for a few main reasons:</p> <h3>It's Useful as a Factory</h3> <p>Having a central core object that you use to get and load other objects eliminates the need for other people to know the dependencies of other objects they might need to use in your framework. For example, a typical user just knows they want to use the Router, but they don't want to have to build it themselves each time they want to use it.</p> <p>Users would rather write:</p> <pre><code>$router = $kernel-&gt;router(); </code></pre> <p>Than something like:</p> <pre><code>$router = new SomeFramework\Http\Router(new SomeFramework\Http\Request()); </code></pre> <p>Or:</p> <pre><code>$router = SomeFramework\Http\Router::getInstance(); </code></pre> <h3>Instance Management</h3> <p>A central core object can also ensure that objects don't get instantiated multiple times when it's not necessary. It's usually not necessary for objects like Request, Response, Router, Session, etc. to have multiple instances.</p> <p>So a call to retrieve a Request instance like this:</p> <pre><code>$request = $kernel-&gt;request(); </code></pre> <p>Will automatically create and instantiate a new Request object on the first call, and then use a simple class-level cache to store the instance for use on subsequent calls to reduce overhead.</p> <h3>Simplifies Dependency Handling</h3> <p>A central core or kernel object can also be useful to simplify dependency handling within the framework itself (usage as a Service Locator). Instead of having to know object inter-dependencies up front, you just pass the core object and know that anything needed can be retrieved directly from it. This is especially useful in frameworks, because you never know what users will want to do within their controllers. You just provide them a central core object, and they can pull anything they need from it. It's worth saying that this Service Locator style approach does come with the known caveat of creating dependencies on the Service Locator itself by all the objects that use it. The drawback is a tradeoff you may or may not want to live with, but it vastly simplifies user-level code, so it's one I chose to make.</p> <h3>Provides a Central Extension Point</h3> <p>One of the nice things about having a central object exist and be passed around everywhere (and available within any Controller) is that it provides a natural common extension point. Alloy lets users add their own methods on the Kernel object that are proxied through the __call magic function:</p> <pre><code>$kernel-&gt;addMethod('bark', function() { echo 'Woof!'; }); </code></pre> <p>Which allows you to use it anywhere within the application that the Kernel is available:</p> <pre><code>$kernel-&gt;bark(); // echos 'Woof!' </code></pre> <p>This provides a nice way for things like plugins to provide custom functionality or create their own factory methods on the kernel for helper object creation, etc. without having to create a whole new plugin architecture to support it.</p> <h2>Regarding Class Configuration</h2> <p>Regarding your question on why you wouldn't want to do this:</p> <pre><code>$myclass-&gt;get_configs(); // get my configs $myclass-&gt;do_stuff($this-&gt;my_configs); // use them </code></pre> <p>Instead of this:</p> <pre><code>$myclass_configs = $this-&gt;config-&gt;get('configs_for_myclass'); // get configs $this-&gt;myclass = new MyClass($myclass_configs); // call the function and give it the config </code></pre> <p>Is because of two main reasons:</p> <p>(1) Repetitious functionality across all classes for "get_config". To keep the code DRY, you would end up having to make all your classes derive from a common base class, which would most likely constitute inheritance abuse and deepen your class hierarchy.</p> <p>(2) When you make multiple method calls on the object, it would be tedious and ugly to pass in the configs every time, i.e.:</p> <pre><code>$myclass-&gt;do_stuff($this-&gt;my_configs); $myclass-&gt;do_other_stuff($this-&gt;my_configs); $myclass-&gt;do_more_stuff($this-&gt;my_configs); </code></pre> <p>It is much nicer to instantiate the object with configuration once:</p> <pre><code>$myclass = new MyClass($myclass_configs); $myclass-&gt;do_stuff(); $myclass-&gt;do_other_stuff(); $myclass-&gt;do_more_stuff(); </code></pre> <p>And since that configuration has to come from somewhere and you don't necessarily want your users having to type it all out or hardcode it somewhere else, you just have them pull it out of the common core object because it's already loaded the common configuration file that is used across the whole application.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload