Re: [Long] Modular design and issues
Re: [Long] Modular design and issues
- Subject: Re: [Long] Modular design and issues
- From: email@hidden
- Date: Wed, 14 Mar 2007 21:32:35 +0800
Hi,
Do you mind to send the -(NSWindow *)window message to self after you
invoke [super initWithWindowNibName:@"EditCategory"] or in the
beginning of showAddCategorySheetOnWindow?
By doing that, you force EditCategoryController to load the nib so
that you can use those outlets then.
HTH,
James
On Mar 13, 2007, at 5:31 PM, Fabio Mancinelli wrote:
Dear all,
I am developing a Cocoa application and I have some issues at the
design level, so I wanted to ask you what are the "best practices"
in these cases.
My (CoreData) application has 3 Nibs:
1) MainMenu.nib which contains the main window and the
ApplicationController. The main window has a button for managing
"categories" in the data store. (Just for completeness, a Category
is an entity with a name attribute).
2) ManageCategories.nib which contains a window that presents the
list of the currently defined categories and buttons for adding and
removing them. The owner of this Nib file is a
ManageCategoriesController object that subclasses
NSWindowController and implements the application logic.
3) EditCategory.nib which contains a window that has the UI for
creating a new "category", i.e., a "name" text field and two
buttons "OK" and "Cancel". Again, the owner of this Nib file is a
EditCategoryController object that subclasses NSWindowController
and that implements the application logic.
Both ManageCategoriesController and EditCategoryController have the
following designated initializer:
- (id)initWithManagedObjectContext:(NSManagedObjectContext *)moc
This is necessary because both of them need a CoreData context, and
since the objects that will use it (through bindings) reside in
different Nibs I need a way to "propagate" this context from the
ApplicationController instance in the MainMenu.nib to other Nibs.
The ApplicationController code for handling the "manage categories"
action is very simple (and standard):
if(manageCategoriesController == nil) {
manageCategoriesController = [[ManageCategoriesController alloc]
initWithManagedObjectContext:[self managedObjectContext]];
}
[manageCategoriesController showWindow:self];
Everything works fine. The "manage categories" window shows up and
the table is correctly filled with all the information regarding
the available "categories". This design is good because the "manage
categories" functionality is well isolated and loosely coupled (I
might "outsource" completely the development of this part to
another person and "just (re)use it").
So I wanted to apply this design principle to the "edit category"
functionality.
In the "add" action of ManageCategoriesController I do the following:
if(editCategoryController == nil) {
editCategoryController = [[EditCategoryController alloc]
initWithManagedObjectContext:[self
managedObjectContext]];
}
[editCategoryController showAddCategorySheetOnWindow:[self window]];
This time, instead of calling showWindow, I call a custom method
that presents the edit category window as a sheet attached to the
manage category window.
Again everything seems to work fine but... When
showAddCategorySheetOnWindow is called, the outlets that are
connected to the Nib elements (mostly to object and array
controllers) are not initialized. In fact, by putting some NSLog in
different methods I get the following trace:
1) addCategory:(id)sender (in ManageCategoriesController)
2) initWithManagedObjectContext:(NSManagedObjectContext *)moc in
EditCategoryController
3) showAddCategorySheetOnWindow:(NSWindow *)window in
EditCategoryController
4) awakeFromNib in EditCategoryController
The code for initWithManagedObjectContext:(NSManagedObjectContext *)
moc in EditCategoryController invokes
[super initWithWindowNibName:@"EditCategory"], but when it returns
the Nib is still not initialized (this is reasonable otherwise the
awakeFromNib would be useless).
I might modify the design, getting rid of EditCategory.nib and
putting all its content in ManageCategories.nib. And this would be
conceptually acceptable.
I can create an instance of EditCategoryController in the Nib file,
and link it to an outlet of ManageCategoriesController. In this
way, the "add" action would call the showAddCategorySheetOnWindow
on an instance that already exists.
But here I would have another problem. By instantianting the
EditCategoryController in the Nib file I cannot call the
initializer that accepts the CoreData context as parameter, and I
have to find a way to communicate this context to the
EditCategoryController instance.
I see two ways for doing this:
1) I can create a setManagedObjectContext method in
EditCategoryController and call it from the awakeFromNib method of
ManageCategoriesController. But this is ugly because it implements
a 2-step initialization that is error-prone.
2) I can create an outlet in EditCategoryController and link it to
the instance of ManageCategoriesController. So when I need the
CoreData context I just send the managedObjectContext message to
this outlet and retrieve the context. This is also ugly because it
increases the coupling between the two classes.
All the three solutions have "problems" and I cannot identify which
is the "best one" to refine. So the question is: what are the "best
practices" for modularizing Cocoa applications? The example
presented here is quite trivial but it shows some issues that might
be relevant in bigger projects. How do you deal with these issues?
Are there other "design-patterns" that avoid the previously
described problems? Am I missing something?
Thank you for having read such a long post and for your answers.
See you,
Fabio
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden