Eu tenho uma função que recebe um conjunto de parâmetros e depois se aplica a eles como condições para uma consulta SQL. No entanto, embora eu fosse a favor de uma única matriz de argumentos contendo as próprias condições:
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;
}
}
}
Meu colega preferiu listar todos os argumentos explicitamente:
function searchQuery($name = '', $phone = '') {
if ($name) {
$query->where('name', $value);
}
if ($phone) {
$query->join('phone');
$query->where('phone', $value);
}
}
Seu argumento era que, ao listar os argumentos explicitamente, o comportamento da função se torna mais aparente - em vez de ter que se aprofundar no código para descobrir qual $param
era o argumento misterioso .
Meu problema era que isso fica muito detalhado ao lidar com muitos argumentos, como 10 ou mais. Existe alguma prática preferida? Meu pior cenário seria ver algo como o seguinte:
searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')
php
functions
switch-statement
parameters
xiankai
fonte
fonte
foreach
nesse caso, é desnecessário; você pode usar emif(!empty($params['name']))
vez deforeach
eswitch
.!empty($params['name'])
para testar parâmetros - por exemplo, a string "0" estaria vazia. É melhor usararray_key_exists
para verificar a chave ouisset
se você não se importanull
.Respostas:
IMHO seu colega está correto para o exemplo acima. Sua preferência pode ser concisa, mas também é menos legível e, portanto, menos sustentável. Faça a pergunta por que você se incomodou em escrever a função em primeiro lugar, o que sua função 'traz para a mesa' - eu tenho que entender o que faz e como faz, em grande detalhe, apenas para usá-la. Com o exemplo dele, mesmo que eu não seja um programador PHP, posso ver detalhes suficientes na declaração da função que não preciso me preocupar com sua implementação.
Quanto a um número maior de argumentos, isso normalmente é considerado um cheiro de código. Normalmente, a função está tentando fazer muito? Se você encontrar uma necessidade real de um grande número de argumentos, é provável que eles estejam relacionados de alguma forma e pertençam juntos a uma ou poucas estruturas ou classes (talvez até uma variedade de itens relacionados, como linhas em um endereço). No entanto, passar uma matriz não estruturada não faz nada para resolver os odores do código.
fonte
where
argumentos, um parajoin
especificadores etc. Nomeando-os adequadamente, isso ainda seria auto-documentado.Minha resposta é mais ou menos independente da linguagem.
Se o único objetivo de agrupar argumentos em uma estrutura de dados complexa (tabela, registro, dicionário, objeto ...) é passá-los como um todo para uma função, é melhor evitá-lo. Isso adiciona uma camada inútil de complexidade e torna sua intenção obscura.
Se os argumentos agrupados tiverem um significado por si mesmos, essa camada de complexidade ajudará a entender todo o design: nomeie-a como camada de abstração.
Você pode descobrir que, em vez de uma dúzia de argumentos individuais ou uma grande matriz, o melhor design é com dois ou três argumentos, cada um agrupando dados correlacionados.
fonte
No seu caso, eu preferiria o método do seu colega. Se você estivesse escrevendo modelos e eu estivesse usando seus modelos para desenvolvê-los. Vejo a assinatura do método do seu colega e posso usá-lo imediatamente.
Enquanto, eu teria que passar pela implementação de sua
searchQuery
função para ver quais parâmetros são esperados por sua função.Eu preferiria sua abordagem apenas no caso em que a
searchQuery
limitação é procurar apenas em uma única tabela, para que não haja junções. Nesse caso, minha função ficaria assim:Então, eu sei imediatamente que os elementos da matriz são realmente os nomes das colunas de uma tabela específica que a classe que tem esse método representa no seu código.
fonte
Faça os dois, mais ou menos.
array_merge
permite uma lista explícita na parte superior da função, como seu colega gosta, enquanto evita que os parâmetros se tornem difíceis de manejar, como você preferir.Também sugiro usar a sugestão de @ chiborg nos comentários da pergunta - é muito mais claro o que você pretende.
fonte
Além disso, você pode passar uma string semelhante a uma string de consulta e usar
parse_str
(porque parece que você está usando PHP, mas outras soluções provavelmente estão disponíveis em outras linguagens) para processá-la em uma matriz dentro do método:e chame assim
Você pode usar
http_build_query
para converter de uma matriz associativa em uma sequência de caracteres (o inverso queparse_str
ocorre).fonte