Jak sobie radzić z gigantycznymi metodami

Posted by Maciej Gos on Monday, June 12, 2017

TOC

Ile to razy otwieraliśmy jakiś kawałek kodu i nagle szok. Metoda ma 300 linijek i z 6 zmiennych. Jak sobie radzić z gigantycznymi metodami? Przedstawię kilka wypracowanych przepisów na radzenie sobie z legacy code. Nie będą one związane z jakimiś konkretnymi wzorcami itp…

Cały kod jest dostępny na GitHub.

Gigantyczne metody

Tak powiem w tajemnicy, że największa metoda z jaką miałem do tej pory do czynienia miała łącznie 9009 linijek i przyjmowała 25 parametrów. Podręcznikowy przykład clean code.

Według mnie metoda zaczyna się robić za duża gdy nie mieści się w 10 linijkach, oraz ilość parametrów jest większa niż 3.

Co z tym zrobić

Ogarnięcie wielu parametrów

Z parametrami możemy sobie dość łatwo poradzić tworząc prostą klasę POCO i przekazać jako parametr.

Poniżej przykład takiej metody. Do demonstracji specjalnie wybrałem VB.NET ze względu na znikome wsparcie dla refactor ze strony VS.
[code lang=”vbnet”]
Function DoSuperComplicated(ByVal param1 As String, ByVal param2 As String, ByVal param4 As Boolean, ByVal param5 As Boolean, ByVal param6 As Integer, ByVal param7 As String, Optional ByVal param8 As String) As Boolean
If param4 Then
‚Do something
Select Case param2
Case “Somevalue”
While continueValue
‚Do Something
If param5 Then
‚Do something
ElseIf param6 = 1 Then
‚Do something
End If
End While
End Select
End If

Return True
End Function
[/code]

A więc bierzemy się za poprawę takiego kodu. Tworzymy klasę POCO i zmieniamy sygnaturę naszej metody.
[code lang=”vbnet”]
Public Class Parameters
Public Property Param1() As String

Public Property Param2() As String

Public Property Param4() As Boolean

Public Property Param5 As Boolean

Public Property Param6 As Integer

Public Property Param7 As String

Public Property Param8 As String
End Class

Function DoSuperComplicated(ByVal parameters As Parameters) As Boolean
If parameters.Param4 Then
‚Do something
Select Case parameters.Param2
Case “Somevalue”
While continueValue
‚Do Something
If parameters.Param5 Then
‚Do something
ElseIf parameters.param6 = 1 Then
‚Do something
End If
End While
End Select
End If

Return True
End Function

[/code]

Co w sytuacji gdy dostajemy wymaganie od klienta ze zmianą logiki albo stworzenie nowej funkcjonalności? Nie wiemy co robi obecna metoda i biznes również nie jest nas w stanie na to naprowadzić.

Pierwsza myśl, która przychodzi do głowy to zaorać… Później w gąszczu przekleństw i złorzeczeń wobec innych programistów przychodzi inny pomysł do głowy.

Tworzymy coś nowego

W sytuacji jak powyższa staram się stworzyć bibliotekę w C# obok obecnego rozwiązania. Zyskujemy tym możliwość „panowania” nad kodem, oraz możliwości jego testowania.

Poniżej przykład jak można to osiągnąć.
[code lang=”vbnet”]
Private continueValue As Boolean = True

Function DoSuperComplicated(ByVal parameters As Parameters) As Boolean
Dim externalLogic As SomethingNew = New SomethingNew()

If parameters.Param4 Then
‚Do something
Select Case parameters.Param2
Case “Somevalue”
While continueValue
‚Do Something
externalLogic.DoSomethingNew(True)

If parameters.Param5 Then
‚Do something
ElseIf parameters.Param6 = 1 Then
‚Do something
End If
End While
End Select
End If

Return True
End Function
[/code]

Definicja przykładowej logiki w C#
[code lang=”csharp”]
public class SomethingNew
{
///
/// Do something new
///
/// Mark process to execute some custome logic
public void DoSomethingNew(bool proceed)
{
//Do Something
}
}
[/code]

Ulga

Jak widzicie można sobie poradzić z legacy code w całkiem prosty sposób. Nie ma sensu brnąć tygodniami w starym zabagnionym kodzie lepiej, szybciej i taniej będzie zrobić coś z boku.

A więc nie bądźcie przerażeni jak widzicie takie potworki w swojej pracy tylko do dzieła bo to jest proste.

Maciej Gos

真诚赞赏,手留余香

使用微信扫描二维码完成支付


comments powered by Disqus