views:

83

answers:

4

Hi all,

Considering a hypothetical situation where an old, legacy presentation library has been maintained over the years, and has gradually had more and more business logic coded into it through a process of hasty corrections and lack of proper architectural oversight. Alternatively, consider a business class or namespace that is not separated from presentation by assembly boundaries, and was thus capable of referencing something like System.Windows.Forms without being forced to add a reference (a much more sobering action than a simple using clause).

In situations like this, it's not unimaginable that the business code used by this UI code will eventually be called upon for reuse. What is a good way to refactor the two layers apart to allow for this?

I'm loosely familiar with design patterns--at least in principle anyway. However, I don't have a whole ton of practical experience so I'm somewhat unsure of my intuitions. I've started along the path of using the Strategy pattern for this. The idea is to identify the places where the business logic calls up to UI components to ask the user a question and gather data, and then to encapsulate those into a set of interfaces. Each method on that interface will contain the UI-oriented code from the original workflow, and the UI class will then implement that interface.

The new code that wants to reuse the business logic in question will also implement this interface, but substitute either new windows or possibly pre-fab or parameterized answers to the questions originally answered by the UI components. This way, the biz logic can be treated as a real library, albeit with a somewhat awkward interface parameter passed to some of its methods.

Is this a decent approach? How better should I go about this? I will defer to your collective internet wisdom.

Thanks!

+3  A: 

I humbly suggest Model–View–Controller - MVC has a high probability as a successful solution to your problem. It separates various logic, much as you describe.

alt text

HTH

JustBoo
Sadly this particular component has origins in MVC; unfortunately with the way it ended up, there was a metric ton of biz logic in the view, and the model was rife with yes/no MessageBoxes used to course correct during processing. Instead of M,V,C it's M/V/C, if you get my grammatical drift.
bwerks
+2  A: 

You seem to be taking a good approach, in which you break dependencies between concrete elements in your design to instead depend on abstractions (interfaces). When you break dependencies like this, you should immediately start using unit tests to cover your legacy code base and to evolve the design with improved assurance.

I've found the book Working Effectively with Legacy Code to be invaluable in these situations. Also, don't jump right into the patterns without first looking at the principles of object oriented design, like the SOLID principles. They often guide your choice of patterns and decisions about the evolution of the system.

Jordão
I'm used to working in a .NET3.5+ environment, wherein Moq is available as a unit testing resource. This codebase is C#2.0/.NET3.0 based, however, and Moq doesn't exist that far back in time. I've tried rhino before, but as good and powerful as it might be...I really hate it. Are there other alternatives?
bwerks
Also +1 for great book/reading recommendations. Thanks!
bwerks
@bwerks: I'm sorry, at this time I don't have any recommendations for a good mocking framework. Seems like a question for SO.
Jordão
Hey, good point!
bwerks
+1  A: 

I would approach it by clearly identifying the entities and the actions they can do or can be done to them. Then one by one try to start creating independent business logic objects for those refactoring the logic out of the UI, making the UI call to the BL objects.

At that point if I understand your scenario correctly you would have a hand full of BL objects, some portion of which made win forms calls, the win forms calls would need to be promoted out into the UI layer.

Then as JustBoo says, I think you'll have a distinct enough situation to start abstracting out controllers from your BL and UI and make it all function in an MVC design.

Jimmy Hoffa
Jimmy Hoffa huh? Where ARE you Jimmy? It's not under a stadium, that's for sure. :-D
JustBoo
A: 

Okay, given your various comments, I would take Mr. Hoffa's advice and extend it. I'm sure you've heard hard problems should be broken down into ever smaller units of work until they can be "conquered."

Using that technique, coupled with the methodologies of Refactoring could solve your problems. There is a book and lots of information on the web about it. You now have a link. That page has a ton of links to information.

One more link from the author of the book.

So, you refactor, slowly but surely to the creamy goodness of MVC, step-by-step.

HTH

JustBoo