I'm trying to understand how to better implement the Model-View-Controller design pattern.
What object should 'own' the Model object? Should a single Controller instantiate (own) the Model object?
Here is an example scenario:
I have a UITabbarController containing two UIViewControllers (controllerA and controllerB). Obviously neither of these controllers own each other. I have a Model object which contains some data and also performs some network activity. Both controllerA and controllerB need to be able to make changes to the Model object. controllerB needs to know when changes have been made to the Model object (either by controllerA or returned results from the network activity). From recent reading:
Mainly, is there any other way for two Controllers to access (write to) one Model, other than through the Model being a singleton?
Also, when a Controller owns another Controller (eg in a UINavigationController when the root view controller instantiates another view controller to stack on top of itself), would the best method for sharing the Model be for the root view controller to instantiate the Model, and pass it to the next view controller before pushing it onto the nav stack)?
Storing global objects in the AppDelegate gets really ugly as your project scales.
Ask yourself: What is the relationship between this model object(s) and other objects in my application? Is the relationship 1-to-1 or 1-to-n. If you need just one model to be accessed by various objects, then go for the singleton approach. If you need one object to have exactly one model, then keep a pointer to it in that object.
When faced with different, yet computationally correct, design alternatives a few areas to consider
If you start rolling global models into the AppDelegate, you'll eventually create a monolithic class which will be difficult to understand and harder to maintain. If you create a pointer to the model in each controller, you must pass a reference to that model each time a new control is instantiated, and it must pass down the pointer to any needing object which it instantiates. Essentially, you've created a cascading waterfall of passing the same pointer, bloated your interface file and constructor. Imagine if instead of 1 model you need to keep track of 5 model objects. Does it make sense for objects to have 5 pointers for 5 models which need to be passed-along to the constructor each and every time? This is how to make your projects buggy and unmaintainable.
In case it isn't obvious. The AppDelegate is just a singleton. When you roll all your models in your app delegate, you haven't avoided using singletons, you've just created a monolithic one.
Regarding KVO: This depends on what you're trying to accomplish. I'll give an example of where KVO is useful. Supposed you have a model object storing the application's user preferences.
@interface SettingsModel
.....
@property (nonatomic, retain) UIColor * backgroundColor;
@end
Other views in the application should update their background colour immediately whenever this settings changes. This can be solved easily using KVO:
[[SettingsModel getInstance] addObserver:self forKeyPath:@"backgroundColor" options:0 context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"backgroundColor"]){
self.view.backgroundColor = [[SettingsModel getInstance] backgroundColor];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With