I think your example isn't quite up to snuff. In your second code snippet, you'd still (presumably) be dealing with classes (Model
and View
), so this code seems a bit strange to me:
from Model import Model
from View import View
class Controller
def some_function(self):
# How are you calling the method on the class and not the instance?
return Model.add_things(1, 2)
You'd have to do something like return Model().add_things(1, 2)
to get an instance from which to call the add_things
method (unless the function was decorated with classmethod
). However, that wouldn't really make any sense and I'll venture you probably didn't mean that. What you actually seem to be asking for is the difference between initializing an object in the constructor vs using a globally declared instance, so something like this:
# It seems that for your question, it shouldn't really matter whether the
# class `Model` is imported or declared inside the same module. So it could
# be either way.
# 1) class Model(): pass
# 2) from Model import Model
# This would initialize `Model` at the module-level
modelobject = Model()
class Controller
def some_function(self):
# And then it would be possible to use it as you described.
return modelobject.add_things(1, 2)
Back to the question...
To answer you I first had to make you realize what you were really asking. The point is there isn't anything wrong or remotely controversial with importing your Model
or View
from outside vs defining them within the same module they're being used in, so asking about that doesn't really make much sense; the truth is that would really depend on your program structure and, more generally, how big your project is. The bigger and more complex, the more unlikely these classes or collection of classes would intermingle in the same module. They'd get separated into different modules pretty quickly.
So your real question as far as I've understood it is whether or not it's best to initialize a Model
or View
object inside the constructor of your Controller
or to use them as global instances you can call from your Controller
class. Quite frankly, I think what you're really asking about is something akin to a global instance pattern (for example, something like a Singleton
class).
You haven't specifically made use of the term Singleton, but asking for a way to use a globally-declared instance of a class smells very much like this is what you're asking about.
You can read about its pitfalls here, here or here.
A better approach is Dependency Injection.
To reference your original example, it may--with objects lower down in your code hierarchy--be preferable to use the following method (to obtain a single instance throughout your program):
class SubController
def __init__(self, modelobject, viewobject):
self.view = viewobject
self.model = modelobject
In other words, it's not unlike a singleton in that you'd essentially be making use of a single instance, if this is indeed what you need. However, it works not by declaring a global instance (which would introduce coupling and many other problems discussed in the linked articles), but by letting the class acquire its dependencies via the calling context (which has considerable advantages). So you pass around the Model
and View
objects directly via constructor methods as opposed to instantiating them directly inside classes (as in your example) or obtaining them with a globally declared variable.
Of course, you'd always have the main class or function where you'd instantiate these objects and pass them around from there on out. This approach has the benefit of being more flexible later down the road!