Recientemente clasifiqué las especificaciones de la compañía, y entre ellas, "el número de parámetros de una función no debe exceder 4" fue algo controvertido durante la promoción. Si la tarea se puede completar, cuantos menos parámetros, mejor. Controvertido, pero hacerlo puede causar dificultades a la hora de programar, y existe debate sobre si vale la pena. Creo que vale la pena hacer esto para que sea más fácil para las personas que usan funciones. En cuanto a las dificultades en la programación, a menudo se debe a que no estamos familiarizados con algunos métodos para reducir parámetros. Aquí hay algunos resúmenes para su referencia:
1. Utilice estructuras para encapsular parámetros.
Ejemplo: Agregar usuario
Cuerpo de la función original: AddUser (nombre de usuario de cadena, contraseña de cadena, dirección de cadena, teléfono de cadena, edad int)
Refactor: agregue una clase de usuario:
usuario de clase
{
cadena pública Nombre de usuario {obtener; establecer}
contraseña de cadena pública {obtener;
Dirección de cadena pública {obtener;
cadena pública Teléfono {obtener; establecer}
edad int pública {obtener; establecer}
}
Cambie AddUser a: AddUser(Usuario usuario)
Problema: si la clase agregada no se usa en otros lugares, a menudo sentimos que no vale la pena. En este momento, podemos considerar usar clases anónimas para encapsular parámetros.
2. Utilice atributos para reemplazar parámetros.
Si el método AddUser en 1 se coloca en la clase Usuario, entonces los parámetros de usuario en el método AddUser se pueden omitir. A veces se pueden agregar algunos atributos para reducir la cantidad de parámetros en algunos métodos. En el diseño orientado a objetos, los objetos deben ser responsables de sí mismos y las responsabilidades deben estar claramente definidas. La razón por la que un método tiene demasiados parámetros puede ser que el método esté escrito en un lugar donde no debería existir. El modelo de "experto en información" mencionado en el principio GRASP puede reducir la cantidad de parámetros en muchos casos.
Ejemplo: transferencia de cuenta
Función original: Transferencia (Cuenta desde, Cuenta a, dinero decimal)
Refactorización:
código
TransferProcess de clase pública
{
cuenta privada de;
cuenta privada para;
Proceso de transferencia público (Cuenta de, Cuenta a)
{
this.De = de;
this.To = a;
}
Transferencia pública nula (dinero decimal)
{
si (dinero<De.Dinero)
{
From.Money = From.Money - dinero;
A.Dinero = A.Dinero + dinero;
//actualizar base de datos
}
demás
{
lanzar nueva excepción ("Saldo excedido");
}
}
}
Nota: El patrón de experto en información es el principio más básico del diseño orientado a objetos. Cuando diseñamos objetos (clases), si una clase tiene toda la información necesaria para completar una determinada responsabilidad, entonces esta responsabilidad debe asignarse a esta clase para su implementación. . En este momento, esta clase es el experto en información correspondiente a esta responsabilidad.
3. Utilice funciones privadas
Cuando llamamos a una función, a menudo no necesitamos muchos parámetros interactivos, pero cuando proporcionamos parámetros, debemos proporcionar todas las condiciones. En este momento, podemos clasificar las funciones, encapsular las funciones más complejas como privadas y exponerlas. funciones simples. Llame a estas funciones complejas para completar la función. Echemos un vistazo a la implementación del método TextBox en mvc:
código
TextBox de cadena estática pública (este HtmlHelper htmlHelper, nombre de cadena, valor de objeto, IDictionary <cadena, objeto> htmlAttributes) {
return InputHelper(htmlHelper, InputType.Text, nombre, valor, (valor == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
}
cadena estática privada InputHelper (este HtmlHelper htmlHelper, InputType inputType, nombre de cadena, valor de objeto, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<cadena, objeto> htmlAttributes) {
si (String.IsNullOrEmpty(nombre)) {
lanzar una nueva ArgumentException (MvcResources.Common_NullOrEmpty, "nombre");
}
TagBuilder tagBuilder = nuevo TagBuilder("entrada");
... ...
Pero a veces, para brindarle a la persona que llama la máxima flexibilidad, también podemos exponer la sobrecarga de funciones más complejas.
4. palabra clave parámetros
Especifica que cuando el número de parámetros es variable, se utiliza el parámetro del método del parámetro.
uso:
código
vacío estático principal (cadena [] argumentos)
{
UsarParams(1, 2, 3);
}
UseParams vacío estático público (lista de parámetros int [])
{
para (int i = 0; i < lista.Longitud; i++)
{
Console.WriteLine(lista[i]);
}
Consola.WriteLine();
}
Este método en realidad no reduce la cantidad de parámetros, solo simplifica el cuerpo de la función.
5. Utilice clases anónimas para encapsular parámetros.
Conocimientos preparatorios: echemos un vistazo primero al RouteValueDictionary
código
vacío estático principal (cadena [] argumentos)
{
RouteValueDictionary r = nuevo RouteValueDictionary (nuevo { id = 1, nombre = "lfm"});
foreach (var elemento en r)
{
Console.WriteLine("{0}:{1}", elemento.Clave, elemento.Valor);
}
//Console.WriteLine();
}
resultado:
identificación: 1
nombre:lfm
RouteValueDictionary puede almacenar los nombres de atributos y los valores de atributos de las instancias en el diccionario.
Muchos lugares en mvc usan este método para pasar parámetros.
Por ejemplo: <%= Html.ActionLink("Detalles", "Detalles", nuevo { id=item.id })%>
En el cuerpo del método ActionLink, RouteValueDictionary se utiliza para descomponer el objeto anónimo y luego ensamblarlo en el enlace.