Como refatorar função que leva muitas argumentos?
-
05-07-2019 - |
Pergunta
Eu escrevi um wrapper para um objeto COM que apenas strings como entrada de exceção, portanto, em boas práticas OOP Enrolei a string em uma função de modo que era mais fácil de construir e chamada.
Eu só estava me perguntando se alguém poderia pensar em uma maneira melhor de fazer o seguinte código.
Public Function OpenTable(ByVal TablePath As String, Optional ByVal OpenAs As String = Nothing, _
Optional ByVal Hide As Boolean = False, Optional ByVal AsReadOnly As Boolean = False, _
Optional ByVal Interactive As Boolean = True, Optional ByVal Password As String = Nothing, _
Optional ByVal NoIndex As Boolean = False, Optional ByVal ViewAutomatic As Boolean = True) As TableInfo
If String.IsNullOrEmpty(TablePath) Then
Throw New ArgumentNullException("TablePath", "TablePath cannot be null or empty")
End If
Dim Builder = New StringBuilder("Open Table ")
Builder.AppendFormat("{0}{1}{2}", ControlChars.Quote, TablePath, ControlChars.Quote)
If (Not String.IsNullOrEmpty(OpenAs)) Then Builder.AppendFormat(" as {0} ", OpenAs)
If (Hide) Then Builder.Append(" Hide ")
If (AsReadOnly) Then Builder.Append(" ReadOnly ")
If (Interactive) Then Builder.Append(" Interactive ")
If (Not String.IsNullOrEmpty(Password)) Then Builder.AppendFormat(" Password {0} ", Password)
If (NoIndex) Then Builder.Append(" NoIndex ")
If (ViewAutomatic) Then Builder.Append(" View Automatic ")
MyComApp.Do(Builder.ToString)
Dim FileInfo = New IO.FileInfo(TablePath)
Return New TableInfo(FileInfo.Name.Substring(0, InStrRev(FileInfo.Name, ".") - 1))
End Function
A quantidade de argumentos que a função tem que tomar é a minha maior preocupação. Este não é muito ruim, mas existem algumas outras funções que eu posso ter que fazer no futuro que vai demorar muito mais argumentos, por isso estou principalmente à procura de melhores formas de construir grandes funções de argumento.
Solução
Neste caso, parece que muitos dos parâmetros são apenas 'valores de configuração' (que acabam sendo cordas), você pode modificá-lo a aceitar uma única classe para toda a configuração que você prepare antes da chamada e que irá voltar a corda em conformidade.
Algo como
class COMConfiguration {
private bool Hide = false;
private bool AsReadOnly = false;
//and so on...
public void setHide(bool v) { Hide = v; }
//only setters
public string getConfigString() {
StringBuilder sb = new StringBuilder();
if (Hide) { sb.Append(" Hide "); }
if (AsReadOnly) { sb.Append(" ReadOnly "); }
//and so on
return sb.ToString()
}
}
Outras dicas
Uma forma de funções alça que pode levar muitos argumentos é criar um novo tipo de objeto, cujo único propósito é o de argumentos da preensão para essa função. Em seguida, você cria um novo objeto desse tipo, defina as propriedades conforme necessário, em seguida, passar essa referência um objeto para a sua função OpenTable
.
Uma vez que eu não sei a sua linguagem de programação, eu vou manter isso para pseudo-código, mas a minha resposta geral é usar variedade ann como único parâmetro:
function OpenTable( options As array) {
if (options is not array or options is empty) {
Throw exception
}
return_string = "";
if ( key is set ('readOnly', options) and is not empty) {
return_string = return_string + ' readonly';
}
// repeat last 3 lines for all your params
}
Ok a última parte de sua função não faz sentido para mim, mas a idéia de conjunto de parâmetros deve se deparar com que eu penso. Boa sorte.
Você pode mudar todos os seus parâmetros booleanos a um único parâmetro de um enum tipo, marcado como Flags . Aqui está uma declaração de exemplo:
' Define an Enum with FlagsAttribute.
<FlagsAttribute( )> _
Enum TableOptions as Short
Hide = 1
AsReadOnly = 2
Interactive = 4
NoIndex = 8
ViewAutomatic = 16
End Enum