Might Be Patterns

This is a place to list rough ideas that might be patterns in the hopes that knowledgeable visitors will help out with the following tasks:


Proposed patternoid from SteveJorgensen - Proposed name: "Replace Arrow with Result Forwarding".

Say you have something like this Access VBA code.

 Public Sub SetFooTo123()
     Dim ctl As Access.Control
     For Each ctl in Me.Controls
         If ctl.ControlType = acTextbox Then
             If ctl.Name Like "*Foo" Then
                 ctl.Value = 123
             End If
         End If
     Next
 End Sub

This is the ArrowAntiPattern. We could get rid of the arrow using ExtractMethod, but this leads to tightly-coupled, special-purpose procedures.

My idea is that, instead, we flatten the arrow by creating a series of procedure calls, each of which produces a byproduct that is passed to the next, as below. Refactoring is done from the outside in, like peeling an onion. There is, for now, a bit more code here than when we started, but it's mostly more general-purpose code and much less tightly coupled.

It is now possible to test each component atomically, rather than testing all at once, or testing C, then B -> C, then A -> B -> C. Also, it is now trivial to change the order of operations. Note that this is starting to resemble what one might do in a Functional programming language, but without the lazy evaluation. Note that VBA has on Continue statement for loops, so we can't flatten the mini-arrows that way. Of course, if we then implement some sort of Functors, we could get rid of the duplicated ForEach? loops, and if we extract a class for filtering and manipulating Controls collections, we could probably get rid of all the objControls passing, but those are other refactorings.

 Public Sub SetFooTo123()
     Dim ctl As Access.Control
     Dim objControls As Object

Set objControls = Me.Controls Set objControls = ControlsOfType(objControls, acTextBox) Set objControls = ControlsNamedLike(objControls, "*Foo") SetValueOfControls objControls, 123

End Sub

Private Function ControlsOfType( _ InControls As Variant, _ ControlType As AcControlType _ ) As VBA.Collection Dim ctl As Access.Control Dim colResult As New VBA.Collection

For Each ctl In InControls If ctl.ControlType = ControlType Then colResult.Add ctl End If Next

Set ControlsOfType = colResult End Function

Private Function ControlsNamedLike( _ InControls As Variant, _ NamedLike As String _ ) As VBA.Collection Dim ctl As Access.Control Dim colResult As New VBA.Collection

For Each ctl In InControls If ctl.Name Like NamedLike Then colResult.Add ctl End If Next

Set ControlsNamedLike = colResult End Function

Private Sub SetValueOfControls( _ Controls As Variant, _ NewValue As Variant _ ) Dim ctl As Access.Control

For Each ctl In Controls ctl.Value = NewValue Next

End Sub


EditText of this page (last edited September 23, 2004) or FindPage with title or text search