views:

282

answers:

4

I need a modal dialog to gather some user input. I then need the same data to be consumed by the application MainFrame.

Usually my Modal Dialog would have a pointer to some DataType able to store what I need, and I'd be passing this object by reference from the MainFrame in order to be able to recover data once the modal dialog is closed by the user.

Is this the best way of passing around data?

It doesn't feel right!

A: 

Normally you can use a single class or other datatype to transfer data. So the dialog is used to change the properties of the class. Why doesn't this feel right?

[humor] With mainframe, I assume you don't mean the big old (althoug still alive and kicking) computers. Else, I think TCP/IP will be a good choise. [/humor]

Gamecat
doesn't feel right because this way I am coupling boundary objects
JohnIdol
A: 

The very best way of doing this is to package the data into an event and send it out on an event bus.

This decouples the dialog from the mainframe - and if you design the event properly it doesn't limit you to just using a dialog.

Depending on the language and environment this event system can be implemented easily and cheaply. I call my version class based interobject communication.

Richard Harrison
Example please...
Aheho
I am looking for a way of decoupling the boundary objects - so this approach sounds good. If I am wokring on a .NET environment I'd imagine I'd be packaging the data into some kind of EventArgs, what about C++/MFCs?
JohnIdol
The decoupling craze has got to stop, it's gotten to "everything looks like a nail" proportions. This question sounds like a simple application that doesn't require this kind of over-engineering
Aidan Ryan
I can provide a concrete example - it uses inheritance or interfaces and four basic classes that do all of the work.I'll revise my answer to add an example later on today.
Richard Harrison
+3  A: 

Since you are passing data once the user has closed the dialog (presumably on DialogResult.OK), you can easily do this without having a MainFrame reference.

So say you have a TextBox on your dialog, called userNameTextBox and a button that ends the dialog with the OK result. You can either make the userNameTextBox public (not recommended) or add a property to return the text.

public string UserName
{
    get { return userNameTextBox.Text; }
}

And to get this value after the dialog has ended, you just do:

Dialog dialog = new Dialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
    string username = dialog.UserName;
}
Samuel
would you choose this approach - which is a cleaner version of what I am proposing - over the event-based communication?
JohnIdol
I am leaning towards this solution
JohnIdol
+1  A: 

@Samuel's suggestion is perfectly adequate when collecting one or two values from the user.

If you're getting many values then the solution in your question is fine as well.

Don't fall prey to premature optimization and over-engineer a decoupled solution. By boundary object I assume you're referring to the datastructure instance referenced by the mainframe and dialog. What's the problem with the dialog and mainframe both referencing this object? What is the benefit of decoupling the boundary/transfer object in this scenario?

The only decoupling payoff I could see here would be decoupling the mainframe from the specific implementation that delivers the data to it. So rather than the mainframe instantiating Dialog and calling Dialog.ShowModal, dependency injection would provide the mainframe with an IDataYouNeedGetter (which would happen to be the same modal dialog) and at the appropriate time the mainframe would do

myGetter.SetTransferObject(dataStructInstance)
myGetter.GoGetTheData()
// do stuff with dataStructInstance now that myGetter set it up.

BUT, there is no reason to add a layer of indirection unless you already know of a specific need for the decoupling.

Aidan Ryan
By boundary objects I mean instances of classes that represent UI elements (MainFrame/Dialog - etc) - but your considerations are perfectly clear.
JohnIdol