views:

26

answers:

2

I have legacy win.forms application written in pretty straightforward approach where forms communicate with DAL on UI events. For example there are textboxes: login/password, button - "Login" and a click-handler where business logic is implemented (DAL is asked to get user by id/password, if not null - than show next screen, if null - show "retry screen").

I have no ability to rewrite it from scratch (in MVP or View/Document pattern), I just want to separate business logic from handlers: grab existing handlers code that communicate with DAL and group it somewhere out of UI handlers.

Dozens of forms are composed with dozens user controls and it's often not clear who is responsible for business logic. Sometimes it's UI control. But sometimes it's a form, who is listening for custom UI-control event and then implement business logic.

If I separate business logic, who should be responsible to call business logic controllers? Forms, user controls, or forms and user controls simultaneously?

Thank you in advance!

+1  A: 

My subjective opinion would be to decouple as much as you can. Stick all the business object code in a library or class of its own, place all the behavior relating to your business objects that you can into that class. Then allow your UI code to call in. If you need to wait between the communication (such as searching a huge database for log in credentials), halt the UI until it hears a response from your business objects. The advantages of this approach is that you could theoretically distribute it in the future.. having the server running the back-end code and the UI simply sending requests and awaiting responses. Though perhaps I misunderstood your question?

Stefan Valianu
Well, thank you, but it looks like exactly what I'm going to do right now: put business object code in one place (stop the ui handlers and business logic mix). So this code will be accessible from UI via methods. I wonder who shall call these new methods: forms or controls. Imagine I have user control "login": 2 textboxes + 1 button. Shall "login" call business logic method on button click or shall "login" have "OnLogin" event and delegate business logic call to form? Nowadays code has mixed approach: sometimes controls but sometimes forms contains business logic
Andrew Florko
Ahh I see what you mean by forms vs controls now. I'd say go with the least common denominator. If you plan on reusing the form classes with different controls, it would probably be a safer bet to place these calling methods on the forms themselves, and have controls trigger the events. Back to your login example.. if you want some sort of form validation, so let's say the credentials are wrong, you need to display a message.. in my opinion it would be better if the form handled this behavior, as controls should for the most part be unaware of each other.
Stefan Valianu
However, if you're going to follow windows standards, it's a good bet to place all the behavior in the forms, as I would think that's a similar behavior to the afx message map.
Stefan Valianu
+2  A: 

As with most refactoring, take small steps.

Start by extracting the code to a new method. So instead of all the login code in the btnLogin_Click event, you would simply have a method called LogUserIn() or something along those lines.

Once you've done this for some (or all) of the event handlers you'll likely start seeing some common trends. Perhaps there is a log out that is relatively similar. Now you've got two methods for a new class.

You can then start using that class in your event handlers. Something like UserData.Login(name, pw) and UserData.Logout(name)

Don't try to do everything at once. Make a change, verify it works, make another change, verify it works ad naseum.

Remember, you don't have to make the perfect refactoring right out of the gate, even an incremental change sounds like it would be a drastic improvement.

taylonr
Thank you, that is about I am going to do at present. But I ask about a bit further step. When I'll put all business logic into separate class(es) from UI handlers who should be responsible to call it? Sometimes it's user controls: btnLogin_Click call UserData.Login(). But may be is should be a form? Login control has OnLogin event form listens to and it's a form who call UserData.Login(). I want some unified approach. Or it will be ok to have mixed code?
Andrew Florko
It would be ok to have mixed approach. However, I would probably go on the side of the event handlers calling the business code. Reason being, if you ever want to change your GUI your new GUI could call into that code, but it might be hard to have your business code listen for different events. Unless I'm unclear on what you're asking.
taylonr
Imagine I have "Login" user control with 2 textboxes and button "Log me in". Who is responsible to call UserData.Login? There are at least 2 places. I can handle btnLogMeIn_Click event and have UserData.Logic call there. Another option to add custom event to login control: OnLoginEvent and handle it in a form. Now form is responsible to call UserData.Login. What do you preffer personally?
Andrew Florko
Personally, I'd have the form. 1) I don't have a lot of user controls 2) You could reuse your UserControl if it simply raised an event. That way, if another project needs your UserControl, you don't have write a new one that calls different business logic. Instead, the hosting form would simply capture the event.
taylonr
Thank you for your patience - you and @Stefan gave the same advise but I would mark Stefan reply as an answer as he has less reputation )
Andrew Florko