T
tam
Many people seem to think that global variables are generally a bad
thing, and I'd be curious as to how those who take that view would
address a problem that I've addressed using a global. Are there
viable alternatives or is this one place where the use is justified?
I have a program where there are many parameters that the user can
specify to control the program. Currently these parameters are
collected into a public static Settings object (similar but not quite
the same as a Java Properties). Whenever any element of the code
needs to know what a parameter is (or if it was specified at all) they
examine this global object.
For example: The program resamples input images into an output
image. So we create the output Image object and as we're setting that
up we create a Sampler object that encapsulates the type of sampling
we want to do. The user starts the code with arguments that can
include
sampler=xxx
where xxx is a short string that indicates the resampler to be used.
The resampler objects are created using a factory that takes the xxx
strings and returns an appropriate object. The factory and the
resampler objects normally know nothing of the Settings object, just
the one string that was used to specify the sampler.
However a few resamplers have specific settings that control their
behavior (e.g., what to do when there is a NaN pixel). With a global
Settings objects that's fine. These classes can find the object and
extract whatever special parameters they need. The great majority of
Samplers that have no special Settings remain blissfully ignorant.
Without a global object, I see two alternatives. First I could pass
an instance of a Settings object around to essentially every object I
create. Almost all the pieces of the program are extensible and even
if something doesn't need to worry about Settings now, some extension
of it might need to in the future. So this drastically increases the
coupling of the system. Instead of being invisibly present everywhere
as a global object, it's visibly present as an argument to all the
factories and constructors. E.g., previously the sampler factory
knew nothing of the Settings, but in this approach it needs to get the
instance and pass it to any samplers it creates.
Alternatively I could require that the string that is passed into the
sampler factory is potentially a complex structure. E.g.,
sampler=xxx/OnNaN=skip/OnInf=skip
rather than
sampler=xxx OnNaN=skip OnInf=skip
As far as the user entry goes there's probably not much difference
here, but now whenever I extract a setting I need to do a lot more
processing to make sure that I find some 'primary key', and modifier
keys and modifier
values and .... Of course we'd use a common class to do all the
parsing, but now all of the code is coupled using this common parser
utility.
Is there some alternative which enables the decoupling that the global
variable approach gives? With this approach the coupling is optional
-- only if a class needs to see the Settings does it need to know
about the class. With the other approaches it seems to me that
virtually all classes will need to see either the Settings or parser
class.
Regards,
Tom McGlynn
thing, and I'd be curious as to how those who take that view would
address a problem that I've addressed using a global. Are there
viable alternatives or is this one place where the use is justified?
I have a program where there are many parameters that the user can
specify to control the program. Currently these parameters are
collected into a public static Settings object (similar but not quite
the same as a Java Properties). Whenever any element of the code
needs to know what a parameter is (or if it was specified at all) they
examine this global object.
For example: The program resamples input images into an output
image. So we create the output Image object and as we're setting that
up we create a Sampler object that encapsulates the type of sampling
we want to do. The user starts the code with arguments that can
include
sampler=xxx
where xxx is a short string that indicates the resampler to be used.
The resampler objects are created using a factory that takes the xxx
strings and returns an appropriate object. The factory and the
resampler objects normally know nothing of the Settings object, just
the one string that was used to specify the sampler.
However a few resamplers have specific settings that control their
behavior (e.g., what to do when there is a NaN pixel). With a global
Settings objects that's fine. These classes can find the object and
extract whatever special parameters they need. The great majority of
Samplers that have no special Settings remain blissfully ignorant.
Without a global object, I see two alternatives. First I could pass
an instance of a Settings object around to essentially every object I
create. Almost all the pieces of the program are extensible and even
if something doesn't need to worry about Settings now, some extension
of it might need to in the future. So this drastically increases the
coupling of the system. Instead of being invisibly present everywhere
as a global object, it's visibly present as an argument to all the
factories and constructors. E.g., previously the sampler factory
knew nothing of the Settings, but in this approach it needs to get the
instance and pass it to any samplers it creates.
Alternatively I could require that the string that is passed into the
sampler factory is potentially a complex structure. E.g.,
sampler=xxx/OnNaN=skip/OnInf=skip
rather than
sampler=xxx OnNaN=skip OnInf=skip
As far as the user entry goes there's probably not much difference
here, but now whenever I extract a setting I need to do a lot more
processing to make sure that I find some 'primary key', and modifier
keys and modifier
values and .... Of course we'd use a common class to do all the
parsing, but now all of the code is coupled using this common parser
utility.
Is there some alternative which enables the decoupling that the global
variable approach gives? With this approach the coupling is optional
-- only if a class needs to see the Settings does it need to know
about the class. With the other approaches it seems to me that
virtually all classes will need to see either the Settings or parser
class.
Regards,
Tom McGlynn