Pergunta

getEmployeeNameByBatchId(int batchID)
getEmployeeNameBySSN(Objecto SOCIAL)
getEmployeeNameByEmailId(String emailID)
getEmployeeNameBySalaryAccount(SalaryAccount salaryAccount)

ou

getEmployeeName(int typeOfIdentifier, byte[] identificador) -> nesta métodos o typeOfIdentifier diz se o identificador é batchID/SSN/emailID/salaryAccount

Uma dessas é a melhor maneira de implementar um método de obter?

Estes métodos seria em um Servlet e chamadas iria ser feita a partir de uma API que seria fornecido para os clientes.

Foi útil?

Solução

Por que não sobrecarregar o getEmployeeName(??) método?

getEmployeeName(int BatchID)
getEmployeeName(objecto SOCIAL)(péssima idéia)
getEmployeeName(String Email)
etc.

Parece um bom 'muitos' abordagem para mim.

Outras dicas

Você pode usar algo como:

interface Employee{
    public String getName();
    int getBatchId();
}
interface Filter{
    boolean matches(Employee e);
}
public Filter byName(final String name){
    return new Filter(){
        public boolean matches(Employee e) {
            return e.getName().equals(name);
        }
    };
}
public Filter byBatchId(final int id){
    return new Filter(){
        public boolean matches(Employee e) {
            return e.getBatchId() == id;
        }
    };
}
public Employee findEmployee(Filter sel){
    List<Employee> allEmployees = null;
    for (Employee e:allEmployees)
        if (sel.matches(e))
            return e;
    return null;
}
public void usage(){
    findEmployee(byName("Gustav"));
    findEmployee(byBatchId(5));
}

Se você fazer a filtragem através de uma consulta SQL que você iria usar a Filter interface para compor uma cláusula WHERE.

A grande vantagem desta abordagem é que você pode combinar dois filtros facilmente com:

public Filter and(final Filter f1,final Filter f2){
    return new Filter(){
        public boolean matches(Employee e) {
            return f1.matches(e) && f2.matches(e);
        }
    };
}

e usá-lo assim:

findEmployee(and(byName("Gustav"),byBatchId(5)));

O que você recebe é semelhante ao Criteria API do Hibernate.

Eu iria com o "muitos" abordagem.Parece mais intuitiva para mim, e menos propenso a erros.

Eu não gosto de getXByY() - que pode ser legal em PHP, mas eu só não gosto de Java (ymmv).

Eu iria com a sobrecarga, a menos que você tenha propriedades do mesmo tipo de dados.Nesse caso, eu gostaria de fazer algo semelhante para a sua segunda opção, mas em vez de usar ints, eu usaria um Enum para o tipo de segurança e clareza.E em vez de byte[], eu gostaria de usar o Objeto (por causa de autoboxing, isso também funciona para as primitivas).

Os métodos são o exemplo perfeito para o uso de sobrecarga.

getEmployeeName(int batchID)
getEmployeeName(Object SSN)
getEmployeeName(String emailID)
getEmployeeName(SalaryAccount salaryAccount)

Se os métodos comuns de processamento de dentro, basta escrever mais getEmplyeeNameImpl(...) e extrair lá o código comum para evitar a duplicação

Primeira opção, sem dúvida.Ser explícito.Ele vai lhe ajudar muito na manutenção e não há realmente nenhuma desvantagem.

@Stephan:é difícil para sobrecarregar um caso como este (em geral), porque os tipos de parâmetro não pode ser discriminatória, por exemplo,

  • getEmployeeNameByBatchId(int batchId)
  • getEmployeeNameByRoomNumber(int roomNumber)

Veja também os dois métodos getEmployeeNameBySSN, getEmployeeNameByEmailId na postagem original.

Vou usar o método explícito de nomes.A todos que mantém o código e a mim, mais tarde vai entender o que esse método está fazendo sem precisar escrever comentários xml.

Às vezes pode ser mais conveniant para usar o especificação padrão de.

Por exemplo:GetEmployee(ISpecification<Employee> especificação)

E, em seguida, começar a definir as suas especificações...

NameSpecification :ISpecification<Employee>
{
private string nome;
público NameSpecification(string nome) { isso.nome = nome;}
public bool IsSatisFiedBy(Funcionário funcionário) { return empregado.Nome == isso.nome;}
}

NameSpecification spec = new NameSpecification("Tim");
Funcionário da tim = MyService.GetEmployee(spec);

Gostaria de usar a primeira opção, ou sobrecarregá-lo, neste caso, de ver como você tem 4 parâmetros diferentes assinaturas.No entanto, ser específico ajuda a compreender o código de 3 meses a partir de agora.

É a lógica dentro de cada um desses métodos, basicamente, as mesmas?

Se assim for, o único método com parâmetro identificador pode fazer mais sentido (simples e redução de código repetido).

Se a lógica/procedimentos variam muito entre os tipos, um método, por tipo, pode ser o preferido.

Como outros sugeriram a primeira opção parece ser bom.O segundo pode fazer sentido quando você estiver escrevendo um código, mas quando alguém vem mais tarde, é mais difícil de descobrir como usar o código.( Eu sei, você tem comentários, e você pode sempre cavar fundo para o código, mas GetemployeeNameById é mais auto-explicativo)

Nota:Btw, o uso do Enum pode ser algo a considerar, em alguns casos.

Em um caso trivial como essa, gostaria de ir com a sobrecarga.O que é:

getEmployeeName( int batchID );
getEmployeeName( Object SSN );

etc.

Somente em casos especiais, eu iria especificar o tipo de argumento o nome do método, isto é,se o tipo de argumento é difícil determinar, se há vários tipos de argumentos tha tem o mesmo tipo de dados (batchId e employeeId, int), ou se a métodos para recuperar o empregado é radicalmente diferente para cada tipo de argumento.

Eu não posso ver por que eu sempre uso esse

getEmployeeName(int typeOfIdentifier, byte[] identifier)

como ele exige tanto de receptor e emissor de chamada para lançar o valor com base no typeOfIdentifier.Projeto ruim.

Se você reescrever a pergunta que você pode acabar se perguntando:

"SELECIONE o nome DO ..."
"SELECIONE SSN DE ..."
"SELECIONE e-mail DE ..."
vs.
"SELECT * FROM ..."

E eu acho que a resposta para isso é fácil e todo mundo sabe disso.

O que acontece se você alterar a classe do Funcionário?E. g.:Você tem que remover o e-mail e adicionar um novo filtro, como departamento.Com a segunda solução, você tem um grande risco de não perceber erros, se você quiser apenas alterar a ordem dos int identificador de "constantes".Com a primeira solução que você sempre vai notar se você estiver usando o método, em algum tempo esquecido classes, de alguma forma você se esqueça de modificar para o novo identificador.

Eu, pessoalmente, prefiro ter o explícito de nomeação "...ByRoomNumber", porque, se você acabar com muitos "sobrecargas" você vai, eventualmente, introduzir erros indesejados.Sendo explícito é imho o melhor caminho.

Concordo com Stephan:Uma tarefa, um nome de método, mesmo se você pode fazê-lo de várias maneiras.A sobrecarga de método recurso foi fornecida exatamente para o seu caso.

  • getEmployeeName(int BatchID)
  • getEmployeeName(String Email)
  • etc.

E evitar a segunda solução a todo o custo.Ele cheira "a tua olde void * de C".Da mesma forma, a passagem de um Java "Objeto" é quase tão ruim que o estilo de um C "void *".

Se você tem um bom design, você deve ser capaz de determinar se você pode usar a sobrecarga de abordagem ou se você está indo para executar um problema onde se sobrepor você vai acabar tendo dois métodos com o mesmo tipo de parâmetro.

A sobrecarga parece ser a melhor maneira inicialmente, mas se você acabar por não ser capaz de adicionar um método no futuro e bagunçar as coisas com nomenclatura que vai ser uma trabalheira.

Pessoalmente, eu iria para a abordagem de um único nome, por método, dessa forma, você não ter problemas mais tarde com a tentativa de sobrepor-se o mesmo parâmetro métodos do Objeto.Também, se alguém estendido sua classe no futuro e implementadas outro vazio getEmployeeName(String nome) ele não iria substituir o seu.

Para resumir, vá com um método único nome para cada método, a sobrecarga pode causar problemas a longo prazo.

A dissociação entre o processo de pesquisa e os critérios de pesquisa jrudolf propõe, no seu exemplo é excelente.Eu me pergunto por que não é o mais votado solução.Posso perder alguma coisa?

Eu iria com Objetos De Consulta.Eles funcionam bem para aceder a tabelas diretamente.Se você está confinado procedimentos armazenados, elas perdem um pouco de sua força, mas você ainda pode fazê-lo funcionar.

O primeiro é, provavelmente, o melhor em Java, considerando que se trata typesafe (ao contrário dos outros).Além disso, para "normal" tipos", a segunda solução parece apenas fornecer complicado de uso para o usuário.No entanto, desde que você está usando o Objeto como o tipo de SSN (que tem um significado semântico, além de Objeto), você provavelmente não vai sair com esse tipo de API.

Tudo-em-tudo, neste caso particular, eu teria usado a abordagem com muitas getters.Se todos os identificadores têm a sua própria classe, tipo, eu poderia ter ido para o segundo percurso, mas a mudança internamente na classe em vez de um ou de aplicação definido pelo tipo de identificador.

vara de todas as suas opções em um enum, a ter algo como o seguinte

GetEmployeeName(Enum identifier)
{
    switch (identifier)
    case eBatchID:
    {
        // Do stuff
    }
    case eSSN:
    {
    }
    case eEmailId:
    {
    }
    case eSalary:
    {
    }
    default:
    {
        // No match
        return 0;
    }
}

enum Identifier
{
    eBatchID,
    eSSN,
    eEmailID,
    eSalary
}

Você está pensando em C/C++.

Use os objetos em vez de um identificador de byte (ou int).

My Bad, a sobrecarga de abordagem é melhor e utilizar o CPF como chave primária não é tão bom

public ??? getEmployeeName(Object obj){

if (obj instanceof Integer){

  ...

} else if (obj instanceof String){

...

} else if .... // and so on


} else throw SomeMeaningFullRuntimeException()

return employeeName
}

Eu acho que é melhor usar Exceções não verificadas para sinalização de entrada incorreta.

Documento-lo para que o cliente saiba quais objetos para esperar.Ou criar seus próprios invólucros.Eu prefiro a primeira opção.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top