Zend_Config_Configurable is an interface indicating configuration facilities of a component. It will unify all components which consume Zend_Config objects for their internal configuration.
<p>There are a number of other components which may implement this interface in the future. The web service consumer components, Zend_Cache, Zend_Translate just to name a few.</p>
<p>This is a good improvement i think. I am using some sort of this code at my projects.</p>
<p>Is it possible that a component uses more than one config object, because you used addConfig. If only one i think it would be better to use setConfig instead.</p>
<p>I can't imagine a usecase for more than one configuration object. Nevertheless addConfig() seems appropriate, as it is not </p>
<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[public static function setConfig()]]></ac:plain-text-body></ac:macro>
<p> for setting a configuration once so you basically add a configuration to an instance. The fact that you can add just one doesn't matter as I suppose.</p>
<p>This seems to be a good idea. Ive recently seen similar at Doctrine.</p>
<p>As mentioned by Wil 'configure' can be renamed to 'newInstance' like 'getInstance' at the Singleton pattern, 'setInstance' from the Registry or even 'newInstance' from spl's 'ReflectClass'.</p>
<p>Configuration of components are often very similar, so maybe an abstract class is an alternative.</p>
<p>As I replied to will, I don't mind changing configure() to a better name, while I had the feeling that configure() hits the purpose pretty well. "newInstance()" is a bit too generic, as it does not explain the pre-condition for the instanciation (which is having a configuration object). "getConfigured()" is long and not easy to spot. So, until now I'm just undecided.</p>
<p>btw: can you explain the idea of the abstract class a bit further as I can't imagine how you mean it.</p>
<p>I dont know, if its useful to force a configuration object on configure()/getInstance(). So if the object can be omitted, getInstance() would fit again <ac:emoticon ac:name="wink" /></p>
<p>A very simple example</p>
<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[abstract class ConfigureAble
{
protected $_options = array ();
public function setOption ($key, $value)
<p>Sry, ive send my post to early <ac:emoticon ac:name="wink" /></p>
<p>What i want to say: Setting and retrieving of options will be very similar in classes, which implement the interface, so it is possible to solve it in a class, which these classes could extends instead. The example ive posted are really simple. So an idea might be to set an option to a set*-method, if one exists. Or a option is only set, if the key is already found in the options-array. I think, the solutions how the interface would be implemented will be very similar.</p>
<p>This is out of scope of this proposal. "Setting and retrieving options" is a more general concept of object configuration, this proposal tries to achieve a generalization of object configuration with Zend_Config objects. As concrete object configuration is a domain specific problem Zend_Config_Configurable is and can be only an interface not an implementation blueprint.</p>
<p>A remark to your example: I think the setProperty($key, $value)/getProperty($key) pattern isn't the best idea as it complicates the API. setPropertySomething($value) is much easier to understand and document.</p>
<p>An abstract class (presumably with default implementations of the interface methods) would probably not be a good idea, since it could break many established class hierarchies. There are plenty of configurable objects that already have parent class that should not be changed.</p>
<p>Of course, if we had mixins, this wouldn't be an issue... <ac:emoticon ac:name="smile" /></p>
<p>I think it's a good idea.<br />
I'm also for changing name from configure() to something conveying the factory idea better. Maybe actually configure() is a better name for addConfig() <ac:emoticon ac:name="wink" /> </p>
<p>Thanks. I'm not sure about the idea of replacing addConfig() with configure(). Your are right, it seems more to follow the "describe a decent behaviour"-paradigm, while the Zend Framework often adopts the "object as a datastructure" paradigm. That's why I chose addConfig().</p>
<p>What about a small vote just to give me a more structured feedback. We have two topics, the factory method for retrieving a configured object and the addConfig()/setConfig()-question. So here are the options:<br />
Topic 1 (factory)</p>
<p>I'll write in getConfigurable() on 1, since that's what you're actually doing. <ac:emoticon ac:name="smile" /> I like configure() to replace addConfig() since add- or setConfig() don't make it clear that the state of the object will likely significantly change. Ultimately, configuring is the important thing that this method does, not really setting the config attribute.<br />
I need something like this for Zend_Build, so I will put it in the Zend_Build component in the hope that you'll be able to get this in to 1.5 and refactor it before the GA. Let me know as soon as you're ready for the core team review.</p>
<p>You have in mind that changing it to configure() would require to break the API for Zend_Layout::setConfig(), Zend_Controller_Router_Rewrite::addConfig() and Zend_Filter_Inflector::setConfig()? I don't care for this but since you have stated that you want to keep the API stable this is maybe an issue. </p>
<p>Sorry, forgot about getConfigurable(). I think this is inappropriate as it seems like it would return an object which is configurable not a configured object what is actually does.</p>
<p>If <code>getConfigurable()</code> (or whatever it ends up being called) returns a configured object, then by definition that object must have been "configurable", right? Otherwise, how did it end up being a "configured object"?</p>
<p>getConfiguredInstance() is probably the best choice, but that's a lot of typing. getConfigured() is a good compromise.</p>
<p>Re: set configuration</p>
<p>configure(), definitely. No API break necessary (at least immediately) in Layout or Rewrite Router--just throw an E_USER_NOTICE and return self::configure($configuration); Then remove those methods in 1.7 or 1.8.</p>
<p>I also think that add or setConfig sounds more than a pure setter for a member variable. Configure() makes clear that something is done with the component. As Wil said already above.</p>
<p>Perhaps one would like to add a more statful component, for that, one wants to add the config object first, without configuring the component and at a later state he wants to trigger configuration of it. So, for that case configure() would be better instead of set/addConfig. I hope you can follow that, since my english is not the best. <ac:emoticon ac:name="wink" /></p>
<p>I would like to see this in 1.5. Keep up the good work.</p>
<p>Lars, this proposal has lots of community feedback on it, and it may be simple enough to get in to 1.6. Is it ready for recommendation? If so, please move it to that section.</p>
<ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Official Comment</ac:parameter><ac:rich-text-body>
<p>This proposal has been moved back to <strong>Ready for Review</strong></p>
<p>Since this proposal is attempting to solve a problem that has far and wide reaching consequences, and since we are approaching 1.6 release, we would like to send this proposal back to Ready For Review. The reasoning is such that we can continue discourse on what the best course of action is, as well as ensure we have the time and resources to dedicate to a proposal like this.</p>
</ac:rich-text-body></ac:macro>
<p>I really like the idea of having a standard interface for configuring objects. However, I don't understand the value of the factory method. What problem is does it solve or benefit does it provide? IMO, we could just drop it, and keep the interface as a nice simple marker for configurable objects, while standardizing the method name. I think the factory just confuses the component's purpose.</p>
<p>Another thing to consider, is that many "configurable" objects in ZF follow a pseudo-standard whereby they accept either an array or a Zend_Config object. IMHO, that is a good practice to preserve, and probably should be reflected in this API.</p>
<p>As for the method name <code>configure()</code> ultimately makes the most sense, but <code>setConfig()</code> is already used and well-understood in the framework.</p>
<ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Official Comment</ac:parameter><ac:rich-text-body>
<p>At this time, the Zend team is opting for convention instead of strong typing. We will be documenting recommendations for configurable objects, along with standard solutions, but will not be creating an interface solution.</p></ac:rich-text-body></ac:macro>
26 Comments
comments.show.hideDec 25, 2007
Lars Strojny
<p>There are a number of other components which may implement this interface in the future. The web service consumer components, Zend_Cache, Zend_Translate just to name a few.</p>
Dec 26, 2007
Thomas Fritz
<p>This is a good improvement i think. I am using some sort of this code at my projects.</p>
<p>Is it possible that a component uses more than one config object, because you used addConfig. If only one i think it would be better to use setConfig instead.</p>
<p>Greetz Tom</p>
Jan 16, 2008
Lars Strojny
<p>I can't imagine a usecase for more than one configuration object. Nevertheless addConfig() seems appropriate, as it is not </p>
<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[public static function setConfig()]]></ac:plain-text-body></ac:macro>
<p> for setting a configuration once so you basically add a configuration to an instance. The fact that you can add just one doesn't matter as I suppose.</p>
Jan 16, 2008
Wil Sinclair
<p>This would be useful in Zend_Build. I'm not that enthused about 'configure' as an factory method name, but that's a minor quibble.</p>
Jan 16, 2008
Lars Strojny
<p>I don't bind my heart to "configure()". I would be fine with something like "newInstance()" or "getConfigured()".</p>
Jan 16, 2008
Sebastian Krebs
<p>This seems to be a good idea. Ive recently seen similar at Doctrine.</p>
<p>As mentioned by Wil 'configure' can be renamed to 'newInstance' like 'getInstance' at the Singleton pattern, 'setInstance' from the Registry or even 'newInstance' from spl's 'ReflectClass'.</p>
<p>Configuration of components are often very similar, so maybe an abstract class is an alternative.</p>
Jan 16, 2008
Lars Strojny
<p>As I replied to will, I don't mind changing configure() to a better name, while I had the feeling that configure() hits the purpose pretty well. "newInstance()" is a bit too generic, as it does not explain the pre-condition for the instanciation (which is having a configuration object). "getConfigured()" is long and not easy to spot. So, until now I'm just undecided.</p>
<p>btw: can you explain the idea of the abstract class a bit further as I can't imagine how you mean it.</p>
Jan 19, 2008
Sebastian Krebs
<p>I dont know, if its useful to force a configuration object on configure()/getInstance(). So if the object can be omitted, getInstance() would fit again <ac:emoticon ac:name="wink" /></p>
<p>A very simple example</p>
<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[abstract class ConfigureAble
{
protected $_options = array ();
public function setOption ($key, $value)
public function setOptions ($options)
{
foreach ($options as $key => $value)
}
public function getOption ($key)
public function getOptions ()
}]]></ac:plain-text-body></ac:macro>
Jan 19, 2008
Sebastian Krebs
<p>Sry, ive send my post to early <ac:emoticon ac:name="wink" /></p>
<p>What i want to say: Setting and retrieving of options will be very similar in classes, which implement the interface, so it is possible to solve it in a class, which these classes could extends instead. The example ive posted are really simple. So an idea might be to set an option to a set*-method, if one exists. Or a option is only set, if the key is already found in the options-array. I think, the solutions how the interface would be implemented will be very similar.</p>
<p>Dont know, if im understandable now ^^</p>
<p>Greetz, Sebastian</p>
Jan 19, 2008
Lars Strojny
<p>This is out of scope of this proposal. "Setting and retrieving options" is a more general concept of object configuration, this proposal tries to achieve a generalization of object configuration with Zend_Config objects. As concrete object configuration is a domain specific problem Zend_Config_Configurable is and can be only an interface not an implementation blueprint.</p>
<p>A remark to your example: I think the setProperty($key, $value)/getProperty($key) pattern isn't the best idea as it complicates the API. setPropertySomething($value) is much easier to understand and document.</p>
Jul 18, 2008
Bryce Lohr
<p>An abstract class (presumably with default implementations of the interface methods) would probably not be a good idea, since it could break many established class hierarchies. There are plenty of configurable objects that already have parent class that should not be changed.</p>
<p>Of course, if we had mixins, this wouldn't be an issue... <ac:emoticon ac:name="smile" /></p>
Jan 16, 2008
Stanislav Malyshev
<p>I think it's a good idea.<br />
I'm also for changing name from configure() to something conveying the factory idea better. Maybe actually configure() is a better name for addConfig() <ac:emoticon ac:name="wink" /> </p>
Jan 17, 2008
Lars Strojny
<p>Thanks. I'm not sure about the idea of replacing addConfig() with configure(). Your are right, it seems more to follow the "describe a decent behaviour"-paradigm, while the Zend Framework often adopts the "object as a datastructure" paradigm. That's why I chose addConfig().</p>
<p>What about a small vote just to give me a more structured feedback. We have two topics, the factory method for retrieving a configured object and the addConfig()/setConfig()-question. So here are the options:<br />
Topic 1 (factory)</p>
<ol>
<li>configure(Zend_Config $config)</li>
<li>getConfigured(Zend_Config $config)</li>
<li>newInstance(Zend_Config $config)</li>
</ol>
<p>Topic 2 (set configuration)</p>
<ol>
<li>setConfig(Zend_Config $config)</li>
<li>addConfig(Zend_Config $config)</li>
<li>configure(Zend_Config $config)</li>
</ol>
Jan 17, 2008
Lars Strojny
<p>My vote:<br />
1: 1<br />
2: 2</p>
Jan 17, 2008
Wil Sinclair
<p>I'll write in getConfigurable() on 1, since that's what you're actually doing. <ac:emoticon ac:name="smile" /> I like configure() to replace addConfig() since add- or setConfig() don't make it clear that the state of the object will likely significantly change. Ultimately, configuring is the important thing that this method does, not really setting the config attribute.<br />
I need something like this for Zend_Build, so I will put it in the Zend_Build component in the hope that you'll be able to get this in to 1.5 and refactor it before the GA. Let me know as soon as you're ready for the core team review.</p>
Jan 17, 2008
Lars Strojny
<p>You have in mind that changing it to configure() would require to break the API for Zend_Layout::setConfig(), Zend_Controller_Router_Rewrite::addConfig() and Zend_Filter_Inflector::setConfig()? I don't care for this but since you have stated that you want to keep the API stable this is maybe an issue. </p>
Jan 17, 2008
Lars Strojny
<p>Sorry, forgot about getConfigurable(). I think this is inappropriate as it seems like it would return an object which is configurable not a configured object what is actually does.</p>
Jul 18, 2008
Bryce Lohr
<p>If <code>getConfigurable()</code> (or whatever it ends up being called) returns a configured object, then by definition that object must have been "configurable", right? Otherwise, how did it end up being a "configured object"?</p>
Jun 18, 2008
Matthew Ratzloff
<p>Re: factory method name</p>
<p>getConfiguredInstance() is probably the best choice, but that's a lot of typing. getConfigured() is a good compromise.</p>
<p>Re: set configuration</p>
<p>configure(), definitely. No API break necessary (at least immediately) in Layout or Rewrite Router--just throw an E_USER_NOTICE and return self::configure($configuration); Then remove those methods in 1.7 or 1.8.</p>
Jan 18, 2008
Thomas Fritz
<p>My Vote:<br />
1: 2<br />
2: 3</p>
<p>I also think that add or setConfig sounds more than a pure setter for a member variable. Configure() makes clear that something is done with the component. As Wil said already above.</p>
<p>Perhaps one would like to add a more statful component, for that, one wants to add the config object first, without configuring the component and at a later state he wants to trigger configuration of it. So, for that case configure() would be better instead of set/addConfig. I hope you can follow that, since my english is not the best. <ac:emoticon ac:name="wink" /></p>
<p>I would like to see this in 1.5. Keep up the good work.</p>
Mar 08, 2008
Sebastian Krebs
<p>I would also like to see this in the future. I think in 1.5 it will not appear <ac:emoticon ac:name="wink" /></p>
Jun 18, 2008
Wil Sinclair
<p>Lars, this proposal has lots of community feedback on it, and it may be simple enough to get in to 1.6. Is it ready for recommendation? If so, please move it to that section.</p>
<p>,Wil</p>
Jun 18, 2008
Lars Strojny
<p>Done</p>
Jul 02, 2008
Ralph Schindler
<ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Official Comment</ac:parameter><ac:rich-text-body>
<p>This proposal has been moved back to <strong>Ready for Review</strong></p>
<p>Since this proposal is attempting to solve a problem that has far and wide reaching consequences, and since we are approaching 1.6 release, we would like to send this proposal back to Ready For Review. The reasoning is such that we can continue discourse on what the best course of action is, as well as ensure we have the time and resources to dedicate to a proposal like this.</p>
</ac:rich-text-body></ac:macro>
Jul 18, 2008
Bryce Lohr
<p>I really like the idea of having a standard interface for configuring objects. However, I don't understand the value of the factory method. What problem is does it solve or benefit does it provide? IMO, we could just drop it, and keep the interface as a nice simple marker for configurable objects, while standardizing the method name. I think the factory just confuses the component's purpose.</p>
<p>Another thing to consider, is that many "configurable" objects in ZF follow a pseudo-standard whereby they accept either an array or a Zend_Config object. IMHO, that is a good practice to preserve, and probably should be reflected in this API.</p>
<p>As for the method name <code>configure()</code> ultimately makes the most sense, but <code>setConfig()</code> is already used and well-understood in the framework.</p>
Dec 16, 2008
Matthew Weier O'Phinney
<ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Official Comment</ac:parameter><ac:rich-text-body>
<p>At this time, the Zend team is opting for convention instead of strong typing. We will be documenting recommendations for configurable objects, along with standard solutions, but will not be creating an interface solution.</p></ac:rich-text-body></ac:macro>