Recentemente resolvi as especificações da empresa, e entre elas, “o número de parâmetros de uma função não deve ultrapassar 4” foi um tanto controverso durante a promoção. Se a tarefa puder ser concluída, quanto menos parâmetros, melhor. controverso, mas fazê-lo pode causar dificuldades durante a programação e há debate sobre se vale a pena. Acho que vale a pena fazer isso para facilitar para quem usa funções. Quanto às dificuldades de programação, muitas vezes é porque não estamos familiarizados com alguns métodos de redução de parâmetros.
1. Use estruturas para encapsular parâmetros
Exemplo: Adicionar usuário
Corpo da função original: AddUser (string userName, string password, string address, string phone, int age)
Refatorar: adicione uma classe User:
classe Usuário
{
string pública Nome do usuário {obter;
string pública Senha {obter;
endereço de string pública {obter conjunto;
string pública Telefone {obter definido;
public int Idade {obter definido;
}
Altere AddUser para: AddUser(Usuário usuário)
Problemas: Se a classe adicionada não for usada em outro lugar, muitas vezes sentimos que não vale a pena neste momento, podemos considerar o uso de classes anônimas para encapsular parâmetros.
2. Use atributos para substituir parâmetros
Se o método AddUser em 1 for colocado na classe User, então os parâmetros do usuário no método AddUser podem ser omitidos. Às vezes, alguns atributos podem ser adicionados para reduzir o número de parâmetros em alguns métodos. No design orientado a objetos, os objetos devem ser responsáveis por si mesmos e as responsabilidades devem ser claramente definidas. A razão pela qual um método tem muitos parâmetros pode ser porque o método está escrito em um local onde não deveria existir. O modelo de "especialista em informação" mencionado no princípio GRASP pode reduzir o número de parâmetros em muitos casos.
Exemplo: transferência de conta
Função original: Transferência (conta de, conta para, dinheiro decimal)
Refatoração:
código
classe pública TransferProcess
{
conta privada de;
conta privada para;
public TransferProcess(Conta de, Conta para)
{
isto.De = de;
isto.Para = para;
}
transferência pública nula (dinheiro decimal)
{
if (dinheiro<From.Money)
{
From.Money = From.Money - dinheiro;
To.Money = To.Money + dinheiro;
//atualiza banco de dados
}
outro
{
throw new Exception("Saldo excedido");
}
}
}
Nota: O padrão especialista em informações é o princípio mais básico do design orientado a objetos. Quando projetamos objetos (classes), se uma classe possui todas as informações necessárias para completar uma determinada responsabilidade, então essa responsabilidade deve ser atribuída a esta classe para implementação. . Neste momento, esta classe é o especialista em informação correspondente a esta responsabilidade.
3. Use funções privadas
Ao chamar uma função, muitas vezes não precisamos de muitos parâmetros interativos, mas quando fornecemos parâmetros, precisamos fornecer todas as condições. Neste momento, podemos classificar as funções, encapsular as funções mais complexas como privadas e expor as funções. funções simples. Chame essas funções complexas para completar a função. Vamos dar uma olhada na implementação do método TextBox no mvc:
código
string estática pública TextBox(this HtmlHelper htmlHelper, nome da string, valor do objeto, IDictionary<string, object> htmlAttributes) {
return InputHelper(htmlHelper, InputType.Text, nome, valor, (valor == nulo) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
}
string estática privada InputHelper (este HtmlHelper htmlHelper, InputType inputType, nome da string, valor do objeto, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<string, object> htmlAttributes) {
if (String.IsNullOrEmpty(nome)) {
lançar novo ArgumentException(MvcResources.Common_NullOrEmpty, "nome");
}
TagBuilder tagBuilder = new TagBuilder("entrada");
... ...
Mas às vezes, para dar flexibilidade máxima ao chamador, também podemos expor a sobrecarga de funções mais complexas.
4. palavra-chave params
Especifica que onde o número de parâmetros for variável, o parâmetro do método do parâmetro será usado.
uso:
código
vazio estático principal(string[] args)
{
UseParams(1, 2, 3);
}
public static void UseParams(params int[] lista)
{
for (int i = 0; i < lista.Comprimento; i++)
{
Console.WriteLine(lista[i]);
}
Console.WriteLine();
}
Na verdade, esse método não reduz o número de parâmetros, mas apenas simplifica o corpo da função.
5. Use classes anônimas para encapsular parâmetros
Conhecimento preparatório: vamos primeiro dar uma olhada em RouteValueDictionary
código
vazio estático principal(string[] args)
{
RouteValueDictionary r = new RouteValueDictionary(new { id=1,name="lfm"});
foreach (var item em r)
{
Console.WriteLine("{0}:{1}", item.Key, item.Value);
}
//Console.WriteLine();
}
resultado:
identificação:1
nome:lfm
RouteValueDictionary pode armazenar nomes de atributos e valores de atributos de instâncias no dicionário.
Muitos lugares no mvc usam esse método para passar parâmetros.
Por exemplo: <%= Html.ActionLink("Detalhes", "Detalhes", new { id=item.id })%>
No corpo do método ActionLink, RouteValueDictionary é usado para decompor o objeto anônimo e depois montá-lo no link.