2008-12-02 30 views
8

Tengo alrededor de 8-9 parámetros para pasar en una función que devuelve una matriz. Me gustaría saber que es mejor pasar esos parámetros directamente en la función o pasar una matriz en su lugar? ¿Cuál será una mejor manera y por qué?Acerca del paso de muchos parámetros

Respuesta

11

Si yo haría cualquier cosa, entonces sería crear una estructura que contenga todos los parámetros para obtener una buena inteligencia y nombres fuertes.

public struct user 
{ 
    public string FirstName; 
    public string LastName; 
    public string zilionotherproperties; 
    public bool SearchByLastNameOnly; 
} 
public user[] GetUserData(user usr) 
{ 
    //search for users using passed data and return an array of users. 
} 
+1

¡Programación WIN32 en su máxima expresión! ;-) –

+0

Soy un programador de VB, así que si mi ejemplo infringe algunas reglas de diseño de C#, me disculpo. Pero prefiero enviar objetos en lugar de parámetros si todos los parámetros están vinculados a un objeto natural como en el caso del "usuario". ;) – Stefan

+1

Tendría que estar en desacuerdo, su ejemplo se ve bien porque asumió que los parámetros de entrada están relacionados (todos los miembros de un usuario) pero ese no es siempre el caso. – hhafez

6

pasarlos de forma individual, ya que:

  • que es la forma de tipo seguro.
  • IntelliSense lo recogerá en Visual Studio y cuando escriba sus funciones de llamada, sabrá qué es qué.
  • Es más rápido ejecutar de esa manera.

Si el parámetro realmente ES la matriz, pase la matriz. Ejemplo:

Para las funciones que se parecen a esto, utilice esta notación:

Array FireEmployee(string first, string middle, string last, int id) {...} 

Para las funciones que se parecen a esto, utilizar la matriz:

Array FireEmployees(Employee[] unionWorkers) {...} 
2

Asumo que estás usando C# 4 y sólo puede utilizar parámetros con nombre:

FireEmployee(
    first: "Frank", 
    middle: "", 
    last: "Krueger", 
    id: 338); 

Esto hace que el código casi tan legible como VB o Smalltalk. :-)

Si no, me gustaría ir con lo que Dave Markle tiene que decir.

2

Si este es el código de la biblioteca que se verá de mucha utilidad, y si algunos de los parámetros tienen valores típicos que son candidatos para valores predeterminados, debe considerar el consejo de Dave Markle y proporcionar una selección de sobrecargas progresivamente menos parámetros. Este es el enfoque recomendado en las Pautas de diseño de Microsoft Framework.

Alternativamente, se puede obtener un efecto similar con el enfoque de Stefan, mediante el establecimiento de los valores por defecto con inicializadores de miembros y usando una progresión de sobrecargas ctor.

1

Si realmente no quiere pasar en sus argumentos por separado que sugeriría la creación de una nueva clase que encapsula todos sus argumentos. Puede (en Java y probablemente en C#) declarar una clase interna pública dentro de la clase que contiene el método gnarly para este propósito. Esto evita tener clases flotantes que son realmente solo tipos de ayuda.

1

Yo diría pasarlas individualmente también. No me gusta la idea de crear una clase, y pasar esa clase como argumento. Es una forma de acoplamiento sello, lo que significa hacer cambios serán más difíciles ya que una clase utiliza la otra. Y reutilizar una clase significa que tendrías que reutilizar la otra también.

Se podría utilizar un interfaz para reducir el acoplamiento sello, pero eso es demasiado trabajo para mi gusto, así que por eso me gusta pasar los argumentos individualmente.

-1

No pasarlos como una matriz a menos que la función actúa sobre una matriz, yo no crear una nueva estructura de datos, ya sea para agrupar los parámetros para los siguientes reasones

  1. aprobación de una nueva estructura de datos cueros cuál es la función que realmente necesita como entrada (no se necesita toda la estructura de datos/parte de ella?)

  2. relacionadas con: 1 hace que los UT más difícil (al escribir un UT necesita volver a crear toda la estructura de datos)

  3. Si los parámetros de entrada no están relacionados, termina con una nueva estructura de datos que agrupa tipos de datos no relacionados por el simple hecho de hacer que una llamada funcione más nítida

  4. Si elige pasar la nueva estructura de datos a su función la función no se puede utilizar en un ámbito en el que se define la nueva estructura de datos

Realmente la única desventaja a pasar cada parámetro de la función es que puede que no sea capaz de adaptarse a la función en una línea de código, pero no olvide las líneas que necesita antes de la llamada a la función en la que completará su estructura de datos.

0

¿Realmente necesita 8-9 parámetros para una sola función? Me parece que si necesita tantos parámetros, entonces probablemente esté haciendo demasiadas cosas diferentes en esa función. Intente refactorizar el código en funciones separadas para que cada función tenga exactamente un propósito.

+0

¿Y luego qué? ¿Agregar un comentario de que siempre se deben llamar las 6 funciones relacionadas en secuencia? –

4

Su escenario está cubierto por la refactorización Introducir objeto de parámetros en el libro de refactorización de Martin Fowler. Vale la pena que valga la pena el libro, pero para los que no lo hacen, la refactorización se describe here. También hay una vista previa en el publisher's site, y en los libros de Google. Recomienda reemplazar los parámetros no con una matriz, sino con un nuevo objeto.

+1

Aquí hay recursos más increíbles sobre patrones e.t.c .: http://sourcemaking.com/refactoring/introduce-parameter-object. Y respecto al patrón en sí, supongo que la idea clave de esto es agrupar los parámetros 'relacionados' en objetos, no en todos los parámetros, sino solo estrechamente relacionados. –

+0

Desafortunadamente, @Dmitry, el enlace que ha publicado se refiere a un sitio que parece una infracción de derechos de autor bastante flagrante del libro de refactorización de Martin Fowler, por lo que probablemente debería eliminarlo. Por otro lado, su aclaración de que los parámetros deben estar relacionados entre sí cuando se aplica esta refactorización es útil, gracias. –

+0

definitivamente no. Entonces todos deberían eliminar todos los enlaces a Wikipedia e.t.c. 'Sourcemaking' es un catálogo de patrones, gráficos UML, antipatrones y, por tanto, cuarto. Simplemente consolidó todo el conocimiento público sobre la arquitectura. ¿Conoces un recurso mejor con una descripción más completa de estas cosas? Y está licenciado bajo Creative Commons por cierto. Amo mucho a Fowler, creo que es increíble, pero su libro 'Refactorización' contiene solo una parte de este conocimiento. –

3

Con respecto al comentario Skeets en mi ejemplo anterior que iba a usar una clase en lugar de una estructura y tal vez hacerlo más claro dónde utilizar una clase y dónde utilizar una estructura puedo enviar esto también. Creo que hay otros que también sienten curiosidad por esto.

La razón principal para usar una clase como pude ver es que podrías hacerla inmutable, ¿pero eso también es posible con las estructuras?

por ejemplo:

struct user 
{ 
public user(string Username, string LastName) 
{ 
    _username = Username; 
} 
private string _username; 
public string UserName { 
    get { return _username; } 
} 

}

tengo mucho tiempo sentí que no sé las diferencias más entre las clases y estructuras ahora cuando podemos tener la característica, inicializadores, campos y exactamente todo lo que una la clase también tiene una estructura. Sé que las clases son tipos de referencia y las estructuras son tipos de valores, pero ¿qué diferencia hay en el caso anterior cuando se usa como parámetro en una función?

me encontré con esta descripción de las diferencias en el sitio http://www.startvbdotnet.com/oop/structure.aspx y que la descripción es exactamente cómo Me asignan en mi cabeza:

Las estructuras pueden ser definidos como una herramienta para el manejo de un grupo de lógica relacionados elementos de datos.Son definidos por el usuario y proporcionan un método para que reúne datos de diferentes tipos . Las estructuras son muy similares a las clases . Como Classes, también pueden contener miembros como campos y métodos . La principal diferencia entre las clases y estructuras es que las clases son y los tipos de referencia son tipos de valores. En términos prácticos, las estructuras se usan para objetos más pequeños que no duran persisten por mucho tiempo y las clases se usan para objetos más grandes que se espera que existan en la memoria por períodos largos.

Tal vez esto debería ser una pregunta propia, pero sentí que estaba relacionado cuando todos teníamos diferentes puntos de vista sobre la estructura vs clase-cosa como parámetro.

+0

No olvide que en las versiones más recientes de C# puede guardar algunos tipos de escritura mediante el uso de propiedades automáticas de solo lectura como esta: public string UserName {get; conjunto privado; } –

Cuestiones relacionadas