Existem argumentos objetivos a favor ou contra o uso de objetos versus ID exclusivo como parâmetros de método / função? (e membros de outros objetos?). Especialmente no contexto de linguagens de tipo estaticamente (C # / Java / Scala)
Prós do próprio objeto:
- Mais chamadas seguras. Com os IDs, existe o risco de ordem incorreta dos argumentos. Isso pode ser atenuado, mantendo uma classe 'mini' para cada classe que armazena apenas o ID dessa classe.
- Obtenha uma vez de persistência, não há necessidade de obter novamente
- Com o ID, se o tipo de ID mudar, digamos int -> long, isso exigiria alterações gerais, com possibilidade de erros. (Cortes: https://softwareengineering.stackexchange.com/a/284734/145808 )
Profissionais do uso do ID:
- Na maioria das vezes, não é necessário o objeto real, apenas o uniqueid faria, portanto, ter o ID economiza tempo para obtê-lo da persistência.
Uma mistura dessas técnicas, até onde posso ver, teria apenas contras de ambos e profissionais de nenhuma das duas.
Dado que este é um problema definido concretamente, espero que haja respostas objetivas e não os tipos "eu acho" ou "eu gosto" ... :-).
EDIT: Contexto sobre a sugestão de um comentarista. A única restrição é uma linguagem de tipo estaticamente. O aplicativo é um aplicativo de uso geral, embora tenha prazer em obter respostas com base em cenários de uso específicos.
EDIT: Um pouco mais de contexto. Digamos que eu tenha um sistema de gerenciamento de livros. Meu modelo é:
Book: { id: Int, isbn: String, donatedBy: Member, borrowedBy: Member }
Member: {id: Int, name: String}
Table- wishlist: { isbn: String, memberId: Int}
Table- borrows: { id: Int, memberId: Int}
Method:
isInWishList( book: Book, member: Member ) vs isInWishList( bookId: Int, memberId: Int)
handleBorrowRequest( memberId: Int, book: Book ){
//the login system doesn't actually get the entire member structure, only the member id. I don't need the full member yet. can run a query to verify that the memberId has less than max allowed books for borrowing.
}
Por que eu gostaria de manter apenas o id e não o membro completo? Digamos que quando recebo informações sobre o livro, raramente preciso saber quem o doou ou pediu emprestado. Obter as informações completas para preencher os campos doados e emprestados é um exagero.
Claro, esses são apenas meus pontos. Tenho certeza de que estou perdendo as coisas, então queria saber quais são os pontos a favor / contra.
Respostas:
Dependendo do ambiente e do contexto do problema, a necessidade de acessar o banco de dados pode ser atenuada e, como resultado (IMO), o argumento para usar apenas os IDs é perdido.
Por exemplo, o Doctrine2 ORM do PHP
EntityManager::getReference
produz um proxy carregado lentamente para uma entidade usando o ID fornecido; Não sei quantos outros ORMs fazem isso, mas corresponde aproximadamente à noção de uma "mini-classe" mencionada. Para a maioria das intenções e propósitos, essa é uma entidade totalmente hidratada, para que você possa distribuí-la e usá-la como qualquer outra.O único caso em que não é é quando recebe um ID inválido e, nesse caso, você deseja ir ao banco de dados para validar; além disso, para reduzir o custo de obtenção de entidades, a maioria dos ORMs tem a funcionalidade de cache (primeiro e segundo nível) disponível de alguma forma.
Depois que reduzimos a necessidade e o custo de acessar o banco de dados, ficamos em grande parte com profissionais de usar a entidade como parâmetro:
Obviamente, há casos em que se pode querer passar apenas um ID: por exemplo, ao cruzar um limite de contexto limitado (na fala do design orientado a domínio). Se considerarmos dois contextos limitados com noções diferentes do que compõe uma conta (por exemplo, finanças x relações com clientes), não podemos passar a conta do contexto A para o contexto B. Em vez disso, um ID de conta (no idioma do domínio) pode ser passado.
fonte
Para esse tipo de pergunta, eu delego para a solução que melhor comunica minha intenção como programador e facilita o trabalho de "Future Greg".
O uso do objeto como argumento torna mais fácil acertar a chamada do método daqui a seis meses e esqueci os detalhes dessa aplicação. Para desenvolver o seu "este livro está no exemplo da lista de desejos dessa pessoa", digamos que o
isInWishList
método realmente precise apenas comparar os IDs inteiros de livros e membros. Na realidade, esse método só precisa de dois dados para realizar seu trabalho. Agora, vamos dar um passo atrás neste método único e examinar todo o sistema de software. Duvido que exija apenas um ID do livro e um ID do membro para operar. Você estará retirando o livro e o membro completos do banco de dados de qualquer maneira antes mesmo de chamar,isInWishList
porque é provável que precise fazer algo mais do que apenas chamar esse método. Talvez você faça, mas na maioria das vezes você precisará fazer mais.Dado isso, você realmente não sofrerá uma penalidade de desempenho ao buscar e mapear os dois objetos na íntegra no banco de dados. Teoricamente, você precisará de menos chamadas ao banco de dados, mas na prática descobrirá que isso simplesmente não é verdade. Se você passar esses IDs como parâmetros na string de consulta de volta ao servidor, sim, será necessário buscar a lista de desejos no banco de dados. Mas essa é uma visão muito restrita de todo o seu aplicativo. Haverá cenários quando você estiver executando outras operações, além de verificar uma lista de desejos - por exemplo, adicionando um livro a uma lista de desejos. Você não deseja adicionar itens duplicados.
Ir para a solução que é mais fácil para um novo programador, ou o seu futuro auto entender, o que é passar o
Book
eMember
objetos. Só depois de encontrar um real problema de desempenho que você deve realmente preocupação-se com apenas passando as identificações.Ou então, podemos lembrar que linguagens de tipo estaticamente, como Java, oferecem sobrecarga de método, para que você possa comer seu bolo e comê-lo também:
A resposta real para essa pergunta é escrever os dois métodos, chamar a versão somente número inteiro da versão fortemente tipada e Bob é seu tio.
fonte