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 SubThis 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