commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oliver Heger <oliver.he...@oliver-heger.de>
Subject Re: [ALL] Design question: static utility classes
Date Thu, 29 Aug 2013 18:52:50 GMT
Am 29.08.2013 10:26, schrieb Benedikt Ritter:
> 2013/8/27 Oliver Heger <oliver.heger@oliver-heger.de>
> 
>> Am 27.08.2013 07:06, schrieb Phil Steitz:
>>> On 8/26/13 11:28 AM, Oliver Heger wrote:
>>>> Am 26.08.2013 16:18, schrieb Phil Steitz:
>>>>>
>>>>> On Aug 26, 2013, at 7:38 PM, Oliver Heger <
>> oliver.heger@oliver-heger.de> wrote:
>>>>>
>>>>>> Am 25.08.2013 18:45, schrieb Adrian Crum:
>>>>>>> +1
>>>>>>>
>>>>>>> -Adrian
>>>>>>>
>>>>>>> On 8/25/2013 9:26 AM, James Carman wrote:
>>>>>>>> AtomicReference?
>>>>>> There are multiple aspects here. One is the safe publishing of a
value
>>>>>> written into the member field. This can be achieved by atomic
>>>>>> references, synchronization, or a volatile field.
>>>>>>
>>>>>> The other aspect is that such a field of a static utility class is
>>>>>> pretty global. You cannot have different values for different threads.
>>>>>>
>>>>>> So the question is, is it good design to have static utility classes
>>>>>> with state?
>>>>> Excellent point.  The key question to ask is are there use cases where
>> different threads in the same JVM are really going to want different
>> default factories.  I wonder if any actual user of the current code has
>> ever wanted this.
>>>>>
>>>> In this special case, I *assume* that there are hardly any concrete use
>>>> cases, but of course, we cannot be sure.
>>>>
>>>> However, there may be other examples in [configuration]. Would it make
>>>> sense to be homogeneous here, i.e. use the same design principles for
>>>> all classes?
>>>
>>> Yes and the non-static approach is certainly more flexible, so on
>>> balance I think you and James are right.
>>
>> Many thanks for the feedback! So I think I will go for the "bean-based
>> approach" then.
>>
> 
> One possibility to have the best of both worlds is to create a class with
> all static methods that delegates to an instance that is hold in a static
> field. This would be for all those that want the default behavior. Those
> who need customized behavior could instanciate the delegate directly an
> configure it the way they like:
> 
> public final class BeanHelperUtils {
> 
>    private static final BeanHelper DELEGATE = new BeanHelper(new
> DefaultBeanFactory());
> 
>    public static Bean someMethod() {
>       return DELEGATE.someMethod();
>    }
> 
> }
> 
> public class BeanHelper {
> 
>    private final BeanFactory factory;
> 
>    public BeanHelper(BeanFactory factory) {
>       this.factory = factory;
>    }
> 
>    public Bean someMethod() {
>       factory.createBean();
>    }
> }
> 
> client code can either call BeanHelperUtils.someMethod()
> or create a BeanHelper with the appropriate BeanFactory instance...

I was thinking about such a hybrid approach, too. But then, giving users
too many options and alternatives could be again confusing.

Oliver

> 
> just my 2 cents
> Benedikt
> 
> 
>>
>> Oliver
>>
>>>
>>> Phil
>>>>
>>>> Oliver
>>>>
>>>>> Phil
>>>>>> For users, it may be more convenient to simply access functionality
>>>>>> through static methods, especially if the default values for static
>>>>>> member fields are reasonable for most use cases. However, such a
>> design
>>>>>> makes it impossible to use the represented functionality with
>> different
>>>>>> settings in parallel.
>>>>>>
>>>>>> Also, I am not sure whether complex class loader scenarios (e.g.
an
>>>>>> application server or an OSGi container) may cause problems with
the
>>>>>> static approach.
>>>>>>
>>>>>> Oliver
>>>>>>
>>>>>>>> On Sunday, August 25, 2013, Phil Steitz wrote:
>>>>>>>>
>>>>>>>>> On 8/24/13 11:33 AM, Oliver Heger wrote:
>>>>>>>>>> Hi all,
>>>>>>>>>>
>>>>>>>>>> regarding a principle design question I would like
to get your
>> opinion:
>>>>>>>>>>
>>>>>>>>>> In [configuration] there are a few static utility
classes. One of
>> them
>>>>>>>>>> is BeanHelper which supports the creation of beans
from
>> configuration
>>>>>>>>>> data. The actual bean creation is done by a BeanFactory
which can
>> be
>>>>>>>>>> configured using the static (currently unsynchronized)
>>>>>>>>>> setDefaultBeanFactory() method.
>>>>>>>>>>
>>>>>>>>>> Sebb stated correctly that this approach is thread-hostile
[1]. An
>>>>>>>>>> alternative could be to make BeanHelper a non-static
class which
>> can be
>>>>>>>>>> instantiated and configured per instance. This would
be more
>> flexible
>>>>>>>>>> and would also simplify testing of client code (just
pass in a
>> mock
>>>>>>>>>> object). The drawback is that clients now always
would have to
>>>>>>>>>> create an
>>>>>>>>>> instance, so the API becomes slightly more verbose
- in fact, most
>>>>>>>>>> clients will probably never have the requirement
to change the
>> default
>>>>>>>>>> bean factory.
>>>>>>>>>>
>>>>>>>>>> So, the question is, what do you prefer? The static
approach like
>>>>>>>>>> Object myBean = BeanHelper.createBean(...);
>>>>>>>>>>
>>>>>>>>>> or using an instance as in
>>>>>>>>>> BeanHelper helper = new BeanHelper(myFactory);
>>>>>>>>>> // or use no-args ctor for default factory
>>>>>>>>>> Object myBean = helper.createBean(...);
>>>>>>>>> Personally, I would like the static method better as
a user.
>>>>>>>>> Synchronizing access to the static factory field would
seem to fix
>>>>>>>>> the problem unless I am missing something.  Also, I would
not
>> expect
>>>>>>>>> lots of concurrent access to the getter/setter for this
field in
>>>>>>>>> normal use cases , so the performance overhead of the
sync would be
>>>>>>>>> immaterial.  Having the setter there may also be a little
easier
>> for
>>>>>>>>> dependency injection.
>>>>>>>>>
>>>>>>>>> Phil
>>>>>>>>>> TIA
>>>>>>>>>> Oliver
>>>>>>>>>>
>>>>>>>>>> [1] https://issues.apache.org/jira/browse/CONFIGURATION-486
>>>>>>>>>>
>>>>>>>>>>
>> ---------------------------------------------------------------------
>>>>>>>>>> To unsubscribe, e-mail:
>>>>>>>>>> dev-unsubscribe@commons.apache.org<javascript:;>
>>>>>>>>>> For additional commands, e-mail:
>>>>>>>>>> dev-help@commons.apache.org<javascript:;>
>>>>>>>>>
>> ---------------------------------------------------------------------
>>>>>>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>>>>>>>> <javascript:;>
>>>>>>>>> For additional commands, e-mail:
>>>>>>>>> dev-help@commons.apache.org<javascript:;>
>>>>>>>
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>>>>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>>>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>>
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message