2

I have a relatively large GUI based OOP software (in Python) were I rely heavily on keeping references throughout the program. For example I would define a Main class with some stored options as an attribute (code example below). In a second class, e.g. OptionFrame I would pass the reference to that stored options object and store it again as an attribute. This has the great advantage that if I change the stored options in OptionFrame it will also be changed in Main. However recently I skrewed up the whole program by writting a function that reinitializes the stored options and therefore gives it a new reference, like reset_options_bad in the example below. Therefore the two option objects in OptionFrame and Main were no longer connected and my program did not work anymore.

Was this design decision to rely heavily on passing references around and relying on them a good idea?

Class OptionFrame:
    def __init__(self,options):
        self.options=options

    def change_options(self):
        self.options['example']=False # This should also change the options in main

class Main:
    def __init__(self):
        self.stored_options = {'example':True}   
        self.option_frame = OptionFrame(self.stored_options)

    def reset_options_bad(self):
        self.stored_options = {'example':True} # This is a bad idea

    def reset_options_good(self):
        self.stored_options.clear()
        self.stored_options.update({'example':True})
        self.stored_options
3
  • 2
    Not in python. You are basically stuck with testing for Main.stored_options is Main.options_frame.options everywhere
    – Caleth
    Sep 6, 2017 at 16:14
  • @Caleth Thanks that is a good idea at least. But what to do if the test returns false?
    – Jannick
    Sep 7, 2017 at 8:43
  • Fail fast. Throw an exception detailing what you operation did that, let the process exit, see a failing test. something like this may be useful
    – Caleth
    Sep 7, 2017 at 8:48

1 Answer 1

1

What you basically have is a global variable in disguise. And all the problems of global variables apply. It even gets extra fun when you add a new the reference and you effectively add another global variable.

So I would say it is not a good idea.

10
  • What design pattern would you propose instead?
    – Jannick
    Sep 6, 2017 at 15:13
  • Without knowing the specifics of your situation, my first inclination is toward dependency injection. Inject some kind of service which gets config values (the values themselves, not the object that holds everything). Then if something changes, it returns the correct value. Added benefit that the backing storage can change and the dependent code never needs to know or care.
    – Becuzz
    Sep 6, 2017 at 15:27
  • 1
    Sounds like you're describing a Context object. Isn't a Context object really just a global variable that's being handed around? Sep 6, 2017 at 15:44
  • @RobertHarvey OP basically has the context object already (Only difference to here is Main is creating it, rather than receiving it).
    – Caleth
    Sep 6, 2017 at 16:12
  • So you're saying that a "global variable" is OK, so long as you're injecting it. Sep 6, 2017 at 16:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.