Consequences
Cocoa's NSController subclasses mediate between models and views. The MYShapeEditor example in this chapter identifies some of code that the NSArrayController class replaces in typical applications, but even more controller code can be removed by using Cocoa's NSController subclasses together. Consider the common Master-Detail style of user interface. There is a master list of objects that can be inspected. When one of the objects is selected, details about the selected object are displayed. But what happens when the selected object is complex itself? The details for the selected object might include another list of subobjects used by the selected object. One convenient solution is to chain multiple NSArrayController instances together. The View that displays the selected object's list of subobjects might access the arranged objects of an array controller that that in turn accesses the selected object of another array controller, as shown in Figure 29.6.
Figure 29.6 Mediating controllers are chained together to control complex relationships.
The pattern of chaining mediating controllers together highlights another reason that it is best to store selection information in the Controller subsystem instead of views. The MYShapeEditor example synchronizes selection between two views, but the example can be modified to enable separate selection in the two views simply by using two separate array controllers that both mediate access to the same array of model objects. The MYShapeEditor4 folder at www.CocoaDesignPatterns.com implements the separate selection design shown in Figure 29.7.
Figure 29.7 Separate enable separate selections in the same model.
Cocoa's NSController subclasses reduce the amount of code needed to implement Controller subsystems and incorporate a very flexible design. Managing selection information within the Controller subsystem enables controller chaining and even a few other features that haven't been mentioned yet. For example, a button used to remove currently selected objects from the model should probably be disabled if there are no objects selected. NSArrayController already knows about the selection and even provides a canRemove property suitable for "binding" to a button's isEnabled property.