This hypothetical example illustrates several problems I can’t seem to get past, even though I keep trying!! … Suppose the original code is a long event handler, coded in the UI, triggered when a user clicks a cell in a grid. Expressed as pseudocode it’s:
if Condition1=true then
begin
//loop through every cell in row,
//if aCell/headerCellValue>1 then
//color aCell red
end
else if Condition2=true then
begin
//do some other calculation adding cell and headerCell values, and
//if some other product>2 then
//color the whole row green
end
else show an error message
I look at this and say “Ah, refactor to the strategy pattern! The code will be easier to understand, easier to debug, and easier to later extend!” I get that.
And I can easily break the code into multiple procedures.
The problem is ultimately scope related. Assume the pseudocode makes extensive use of grid properties, values displayed in cells, maybe even built-in grid methods. How do you move all that to another unit, without referencing the grid component in the UI–which would break all the “rules” about loose coupling that make OOP valuable? …
I’m really looking forward to responses. Thanks, as always — Al C.
Refactoring to put code into a separate routine doesn’t necessarily mean decoupling everything. You could just as well refactor each of those cases into a new method belonging to the same class as the event handler you’re refactoring. Those methods would have all the same access to the grid component as your current code already has.
You’re writing code for that event to do things to that grid on that form. Do you really foresee needing to do those operations in response to some other event? Or perform them on some other grid on some other form? If not, then decoupling everything is just an academic exercise and serves no purpose to your product. It’s OK to write application-specific code.
If you want to decouple, then the way to do it is to add parameters to your factored-out routines. If the routines need to work with the grid without knowing exactly which grid it is, then pass the grid in as a parameter: