views:

373

answers:

1

I'm writing some data analysis software and decided to use such approach:

epn:
model/data.py <- Model definition
model/reader.py <- How to read data into model
view/gui.py <- main gui frame (wx)
view/dialogs.py <- different dialogs (wx)
epn.py <- controller

For communication between gui and data I used wx.lib.pubsub. So when button 'Modulation index' is pressed, epn.py catches the message and orders:

self.view.control_panel.displayModulationIndex(self.data.getModulationIndex())

where self.data.getModulationIndex() is:

def getModulationIndex(self):
  m = self.mean_flux
  f = self.fluxes
  # other things

On the other hand I can write it as:

def getModulationIndex(self, m, f)
  # other things

and call it as:

m = self.data.mean_flux
f = self.data.fluxes
self.view.control_panel.displayModulationIndex(self.data.getModulationIndex(m, f))

From my point of view the first example is better (shorter, encapsulated, more error-proof). But it is harder to test it --- you can't just call the method on some mock objects.

hope this one is clear

regards
chriss

+3  A: 

Example 1: "better (shorter, encapsulated, more error-proof)"

Not really.

  • The example 1 function call is no shorter than example 2; you have to set the instance variables before calling the function instead of passing the values as arguments. It's the same code.

  • The example 1 function call is no more encapsulated. Encapsulation is a property of the class as a whole, not an individual method. Methods are just methods, and they often have arguments so that they're clear, obvious, replaceable and easy to test.

  • The example 1 function call is not error-proof in any sense of the word. You're just as likely to forget to set the instance variable as you are to forget to pass the instance variable in the function call.

    When you have explicit arguments (example 2), Python can check to see that you provided the correct number of arguments. In example 1, there's no checking done for you.

Example 1: "harder to test"

Agreed.

Summary

Instance variables are special. They reflect the state of being of some object. For model objects, they're serious business because they're often persistent. For GUI objects, they're "what's being displayed right now" which is often transient.

Don't over-use instance variables. Instance variables should be meaningful and significant. Not just junk variables for things that don't have a proper home anywhere else.

Method functions are just functions. In an OO world, they're still just functions. They map input arguments to output results (or object state changes). Pass all the arguments that make sense.

S.Lott
Thank you for the answer. 1. shorter: I meant that the call in controler layer is shorter. 2. encapsulated: controler layer cannot interfere with data logic, won't pass wrong data to a function. 3. the same as 2. The kind of methods I showed here, work on class members only so it's ok I guess
chriss
@Chriss: It's not shorter. It's the same. You have to prepare two instance variables or two argument values. The instance variable setup is a critical part of the call -- you can't ignore it.
S.Lott
@Chriss: Nothing prevents passing wrong data to a function. You can set the instance variables incorrectly just as often as you provide wrong function-call argument values.
S.Lott