Tengo una función que toma un conjunto de parámetros y luego se aplica a ellos como condiciones para una consulta SQL. Sin embargo, si bien preferí una matriz de argumento único que contenga las condiciones mismas:
function searchQuery($params = array()) {
foreach($params as $param => $value) {
switch ($param) {
case 'name':
$query->where('name', $value);
break;
case 'phone':
$query->join('phone');
$query->where('phone', $value);
break;
}
}
}
Mi colega prefirió enumerar todos los argumentos explícitamente en su lugar:
function searchQuery($name = '', $phone = '') {
if ($name) {
$query->where('name', $value);
}
if ($phone) {
$query->join('phone');
$query->where('phone', $value);
}
}
Su argumento fue que al enumerar los argumentos explícitamente, el comportamiento de la función se vuelve más evidente, en lugar de tener que profundizar en el código para descubrir cuál era el argumento misterioso $param
.
Mi problema fue que esto se vuelve muy detallado cuando se trata con muchos argumentos, como 10+. ¿Hay alguna práctica preferida? Mi peor de los casos sería ver algo como lo siguiente:
searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')
fuente
foreach
es innecesario en este caso, podría usarlo enif(!empty($params['name']))
lugar deforeach
yswitch
.!empty($params['name'])
para probar parámetros; por ejemplo, la cadena "0" estaría vacía. Es mejor usararray_key_exists
para verificar la clave, oisset
si no te importanull
.Respuestas:
En mi humilde opinión su colega es correcto para el ejemplo anterior. Su preferencia puede ser breve, pero también es menos legible y, por lo tanto, menos mantenible. Haga la pregunta por qué molestarse en escribir la función en primer lugar, ¿qué 'trae a la mesa' su función? Tengo que entender lo que hace y cómo lo hace, en gran detalle, solo para usarla. Con su ejemplo, aunque no soy un programador de PHP, puedo ver suficientes detalles en la declaración de funciones que no tengo que preocuparme por su implementación.
En cuanto a una mayor cantidad de argumentos, eso normalmente se considera un olor a código. Por lo general, la función está tratando de hacer demasiado? Si encuentra una necesidad real de una gran cantidad de argumentos, es probable que estén relacionados de alguna manera y pertenezcan juntos en una o unas pocas estructuras o clases (tal vez incluso una matriz de elementos relacionados, como líneas en una dirección). Sin embargo, pasar una matriz no estructurada no hace nada para solucionar los olores del código.
fuente
where
argumentos, uno para losjoin
especificadores, etc.Mi respuesta es más o menos independiente del idioma.
Si el único propósito de agrupar argumentos en una estructura de datos compleja (tabla, registro, diccionario, objeto ...) es pasarlos como un todo a una función, mejor evítelo. Esto agrega una capa inútil de complejidad y hace que su intención sea oscura.
Si los argumentos agrupados tienen un significado en sí mismos, entonces esa capa de complejidad ayuda a comprender todo el diseño: en su lugar, llámelo capa de abstracción.
Puede encontrar que, en lugar de una docena de argumentos individuales o una gran matriz, el mejor diseño es con dos o tres argumentos cada uno agrupando datos correlacionados.
fuente
En su caso, preferiría el método de su colega. Si estabas escribiendo modelos y yo estaba usando tus modelos para desarrollarlos. Veo la firma del método de su colega y puedo usarlo de inmediato.
Mientras tanto, tendría que pasar por la implementación de su
searchQuery
función para ver qué parámetros espera su función.Preferiría su enfoque solo en el caso de que
searchQuery
se limite a buscar solo dentro de una sola tabla, por lo que no habrá uniones. En ese caso, mi función se vería así:Entonces, inmediatamente sé que los elementos de la matriz son en realidad los nombres de columna de una tabla en particular que la clase que tiene este método representa en su código.
fuente
Haz ambas cosas, más o menos.
array_merge
permite una lista explícita en la parte superior de la función, como le gusta a su colega, mientras evita que los parámetros se vuelvan difíciles de manejar, como prefiera.También sugiero usar la sugerencia de @ chiborg de los comentarios de la pregunta: es mucho más claro lo que pretendes.
fuente
También podría pasar una cadena que se asemeje a una cadena de consulta y usarla
parse_str
(porque parece que está usando PHP, pero otras soluciones probablemente estén disponibles en otros idiomas) para procesarla en una matriz dentro del método:y llámalo como
Puede usar
http_build_query
para convertir de una matriz asociativa a una cadena (lo contrario queparse_str
hace).fuente