Application Events: Modeling Selection vs De-Selection as Separate Events?

I’m using my Event Aggregator in my current project to manage communication between a custom control and it’s parent form. This is the same control I talked about in my CQRS Performance Engineering post. It has several drop down lists on it, and each one is progressively filled in based on the value selected in the previous one.

 

Selection

When the user has selected an item from the final drop list (a “product code”), the presenter raises an event through the event aggregator, the parent form receives that event and it uses the information to display the selected item, etc.

 image

 

De-Selection

On the flip side of this, if a user changes their selection on any of the previous drop down lists, the control needs to clear the current product code selection and notify the parent form that the selection has been cleared.

image

I’m currently handling the product code de-selection through the same event as the actual product code selection, but I’m passing a null value for the data inside of the event. The parent form checks for null and if it finds null, it knows to clear the currently selected product code and wait for a new one.

 

The Problem And Possible Solutions

I hate using null like this. It gives me hives and makes me punch my computer when I write code like this. :)

Using a null to model a specific event or variation of an event is a poor choice for determining what behavior and functionality I want, because it is not explicit. The developer that is writing code to handle the product code selection event has to know to check for null and has to know that null means de-select or no selection, and handle it appropriately.

I have two thoughts on how to solve this at the moment:

  1. add some sort of status to the event to tell me if it’s a selection or de-selection or whatever else
  2. model the de-selection as it’s own event

Option #1 would require me to check the status of the event object, which is basically what I’m doing now – only it would be a little easier to know what to do because the status would be more explicitly stated. This is a simple option and would be easy to implement, but I tend to think it’s not the right option.

I’m inclined to say #2 is the right thing to do because it would model two different actions as two different events. Selection and De-selection are not the same thing in my mind. They cause two very distinctly different, but related, sets of behavior in the parent form. It also seems that it would add a little more overhead to the client that needs to know about the events. I’ll have to subscribe to two events now. But that cost seems fair compared to the current implementation and compared to option #1 since I am gaining a better model for the process in question.

 

What Would You Do?

With all that being said, I wanted to toss this out to the world and ask what you would do. Would you leave as a null value in the event data? Would you go with a status on the event data? Would you model is as a separate event? Or would you do something else, entirely?


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Analysis and Design, AppController, Craftsmanship, Messaging, Model-View-Presenter. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Jason Meckley

    I would go with option 2 as well. you already have event aggregation in place. separating the concerns of “selected” & “de-selected” makes sense.

  • Rob

    Try thinking about it from the parent side – what interface would you want.

    Having two events leaves questions like do I get a deslect event before every select event, to indicate the deselection of the previous event.

    I would go for a single event called Change. Then either in the event args or exposed as properties of the control (Sender), you have the “get selected item” / “is there a selected item” logic.

  • Dan

    I’m leaning towards option #2 as well…but have you considered using the Null Object Pattern in your original scenario?

  • http://keithbloom.wordpress.com Keith Bloom

    An explicit event must be simpler, otherwise the selection event will be the selection event with a status to specify if it is a de-selection event, which doesn’t sound good.

    I have recently read the GOF book and the patterns are running around in my head trying to find a place in some code. I am curious to know if a Command object would work here which has the ability to undo the Command issued. Do you know if this is a common use of the pattern?

  • http://www.dennisdoomen.net Dennis Doomen

    What about using the Null Pattern. You surely need the the rest of the product’s info as well. So maybe you can add a public readonly property called Null that returns a special instance of your view model that represents ‘nothing selected’.

  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    @Dan, @Dennis,

    The null object pattern would be a better OO solution, but wouldn’t solve the modeling problem, which is the real problem that I’m trying to address. I do like the null object pattern, though. it solves a lot of OO problems.

    @Keith,

    an undo of hte command would require a memento pattern as well, but would certainly be a possibility, technically. though in this case, i think it would be overkill. i really don’t need an n-level undo and i’m not really dealing with a command at this point. it really is an event – something has happened and the parent form needs to respond – and not a command – something needs to happen, go do it for me.

    @rob,

    a single Change event would be a better option for #1. good suggestion on that one.

    as for the parent and subscribing to two events… the parent will handle either event as distinct things to respond to. the parent cannot assume either of them firing first or second, or having them fired only once. the parent has to be able to respond to any number of either event as they occur. the good news is that it is far easier to code like this than to assume or expect a certain order for the events.

  • Diego

    I don’t have the same concern as you. Passing null back to the listener of the event is better approach. It’s safe in the language, it’s semantics really means “nothing”, it’s easy to check, it’s lightweight (costs an clean IntPtr).

    Why would you think the user HAS to know something which he might not know. I think is way more straight to work with null than with empty object (null pattern).

    BUT, if still you’re not comfortable passing a null back on Selection event, maybe you could take a look at option construct on F#. Maybe you can have something like this in C#.

  • jOE

    1) Does the current solution work?
    2) Why not use full-text to find product codes? Drop downs are evil.

  • http://dazdarevic.net Edin

    I would say that at this point there is no big difference between the two options. If you go with option 1, you kind of follow KISS principle, if you go with option 2 then you’re making things explicit which is a good thing also.

  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    @Diego,

    my response to your comments turned out to be huge. so i posted it as a new entry on it’s own. http://www.lostechies.com/blogs/derickbailey/archive/2010/03/19/a-response-concerning-semantics-and-intention-revealing-code.aspx