Code with many references attributes or methods of another object can be simplifed by introducing a "With ... End With" block. This can be particularly effective if a complex expression is repeated with every reference.
Languages:
Alternatives:
- Consider IntroduceLocalVariable to evaluate a complex expression in only one place.
- FeatureEnvy: Consider ExtractMethod and MoveMethod to put the code in the object where the attributes lie. IntroduceForeignMethod if the target object can't be changed.
Related Refactorings:
- RefactorEliminateWith if it's too sparsely used, or to remedy the FeatureEnvy smell "With" blocks often emit.
[Examples]
In VbClassic: from...
rsObject.Open ...
If rsObject.RecordCount = 0 Then
rsObject.AddNew
rsObject!PK = value
End If
rsObject!Attr = value
to...
With rsObject
.Open ...
If .RecordCount = 0 Then
.AddNew
!PK = value
End If
!Attr = value
End With
PascalLanguage: from...
emp.name := "Joe";
emp.status := "X";
emp.bday.month := 6;
emp.bday.day := 27;
emp.bday.year := 1958;
to...
with emp do
begin
name := "Joe";
status := "X";
with bday do
begin
month := 6;
day := 27;
year := 1958;
end
end
Applicability to other languages: Applies to any language supporting the "with" shorthand. Examples: Pascal
The refactoring can be done one step further, by removing the variable completely:
(Example in VbClassic) from...
set rst = dbs.TableDefs("tblWhatEver").OpenRecordset(dbOpenTable)
If not rst.EOF() Then
rst.AddNew
rst!PK = value
rst.Update
rst.Close
End If
Set rst = Nothing
to...
With dbs.TableDefs("tblWhatEver").OpenRecordset(dbOpenTable)
If not .EOF() Then
.AddNew
!PK = value
.Update
.Close
End If
End With
ContributorsList: JeffGrigg, (name of Pascal example author missing)
[CategoryRefactoring/RefactoringLanguage]