Então, eu tenho um serviço da web que tem algo como um getAccount
onde ele retornaria um identificador para a conta, se o obtivesse, caso contrário, lance uma exceção. O cliente sempre desejará criar uma conta se uma exceção for lançada com as mesmas informações com as quais a obtenção é feita.
Estou criando uma biblioteca de conveniência para os clientes que manipularão todas as chamadas de serviço da Web para que não precisem saber como fazer as chamadas.
O que me pergunto é nesta biblioteca se eu deveria criar um getAccount(accountName)
que obterá a conta, se existir, e se não o criar e retornar as informações, isso é uma coisa ruim a se fazer? Devo deixar que o cliente lide com as exceções ou simplesmente nomeie algo como getOrCreateAccount? Isso importa?
É uma prática ruim criar algo em uma operação get?
fonte
getOrCreateAccount
ou similar.acquire
, gostoacquireAccount
. Ele não tem um significado existente em nenhum dos principais protocolos que encontrei e possui um anel imperativo adequado para isso. "Faça o que for necessário para adquirir um desses para mim. Solicite, construa, falsifique, roube, não me importo, apenas pegue um ou morra tentando."getSomething()
é para getters esetSomething()
é para setters. Imo qualquer coisa que faz algo mais intelectual deve ser chamado outra coisa, ou sejafetchSomething
,obtainSomething
,computeSomething
, oudoSomethingElse
etc.Respostas:
Sim, isso importa. Na minha opinião, geralmente é uma prática ruim criar algo em um procedimento que não esteja documentado como possuindo os poderes de criação. Nomeie o procedimento
getOrCreate...
ou tenha umcreate...
procedimento separado e, se você realmente quiser, faça asgetOrCreate...
primeiras tentativasget...
e, se isso falhar, liguecreate...
e depois ligueget...
.O usuário da biblioteca provavelmente não esperará que o
get...
procedimento seja criado se a operação get falhar. Se eles descobrirem repentinamente que seus testes pedem paraget...
criar uma tonelada de dados, provavelmente ficarão bastante surpresos. E como eles limpam isso? E se eles escreverem código pensando que receberão um erro seget...
falharem e quiserem lidar com isso à sua maneira?fonte
get...
create...
get...
apenas os dois primeiros. Vou falar com o cliente sobre se eles exigirão a capacidade de simplesmente chamar umget
sem querer criar #create
no nome, apenas para ser 100% claro sobre o que está acontecendo.getOrCreate
tem precedência em uma estrutura da web popular: docs.djangoproject.com/en/1.10/ref/models/querysets/…Não, não é 'má prática'. Desde que você e os outros desenvolvedores concordem que é assim que você deseja que funcione, tudo bem. Afinal, seria retornar uma conta, que é o que você deseja. O fato de a conta ser criada "sob o capô" é irrelevante para o chamador.
fonte
Se
getAccount()
sempre puder retornar uma conta, do ponto de vista do chamador, a conta existe e sempre existiu. Não é necessáriogetAccount()
"criar" nada. A conta não precisa ser armazenada em nenhum lugar até que seja diferente da conta padrão.fonte
GetOrCreate
é a semântica errada, mas obter um objeto que possa "logicamente" existir, existindo ou não phyiscally, é bom. Como exemplo, uma matriz esparsa de itens mutáveis pode não ter nenhum armazenamento alocado para o elemento 1.841.533, mas ainda permitir que esse elemento seja "recuperado" criando um novo objeto, armazenando-o e retornando uma referência.Faz mais sentido criar 3 métodos:
getAccount -> O que apenas obtém a conta.
createAccount -> Cria uma conta.
getAccountAndCreateIfNeeded -> Escolha sua própria nomeação;)
Por que a separação: você tem um método simples para obter e criar. Esse é um método claramente testável para ambos. Para getAccount, não é uma exceção não encontrar a conta. Então, basta retornar false ou algo assim, é esperado.
Em seguida, você pode usar esse valor de retorno em sua função agrupada: getAccountAndCreateIfNeeded, que agora também é testável, deve retornar sempre uma conta. O que você pedir.
Todos esses três métodos são claros, é claro o que eles fazem e o que retornam. Você pode fazer acordos agora com sua equipe, mas esse tipo de exceção é terrível a longo prazo. Apenas deixe bem claro e você não terá problemas.
fonte
getAccountIfExists
que obteria uma conta ou indicaria que ela não existe sem a criação de uma nova. OgetAccount
próprio método deve pressupor a existência da conta e, se não houver, lançar uma exceção.Isso depende das circunstâncias.
Por exemplo, você pode usá-lo para fazer carregamento / instanciação lenta, adiando o carregamento de dados ou a criação de uma instância até que seja realmente necessário. Isso normalmente é sensato, pois economiza recursos dos quais você talvez não precise (se a classe / dados nunca for necessário, nunca será carregado).
No entanto, nesse caso em particular, eu diria que ter um método chamado getAccount que criaria uma nova conta se ela não existisse não seria uma boa prática. Se o usuário forneceu algumas credenciais para identificar uma conta específica e essa conta não pôde ser encontrada, isso significa que o usuário ainda não é um cliente e deve ter uma conta criada para ele ou significa que as credenciais foram digitadas incorretamente e o usuário precisa ser solicitado a verificar se inseriu o que pretendia inserir?
Se você possui um método getAccount que cria uma nova conta, caso não consiga identificar uma, não há escolha. Se você dividir a criação e a saída da conta em métodos separados, terá muito mais flexibilidade para decidir o que fazer caso uma tentativa de obter uma conta falhe.
fonte