Есть ли объективные аргументы за или против использования объектов против уникального идентификатора в качестве параметров метода / функции? (а члены других объектов?). Особенно в контексте статически типизированных языков (C # / Java / Scala)
Плюсы самого объекта:
- Более безопасные звонки. С идентификаторами существует риск неправильного упорядочения аргументов. Этого можно избежать, сохранив мини-класс для каждого класса, в котором хранится только идентификатор этого класса.
- Получить один раз от настойчивости, нет необходимости получать снова
- С идентификатором ID, если тип идентификатора изменится, скажем, int -> long, потребуется изменение по всем направлениям с возможными ошибками .. (суд: https://softwareengineering.stackexchange.com/a/284734/145808 )
Плюсы использования ID:
- Большую часть времени нет необходимости в реальном объекте, просто будет uniqueid, поэтому наличие идентификатора экономит время на его получение от постоянства.
Насколько я могу судить, смесь этих техник имела бы только минусы обоих и плюсы ни того, ни другого.
Учитывая, что это конкретно определенная проблема, я надеюсь, что есть объективные ответы, а не - «я думаю» или «мне нравятся» типы ... :-).
РЕДАКТИРОВАТЬ: Контекст по предложению комментатора-Единственное ограничение является статически типизированных языков. Приложение является приложением общего назначения, хотя с удовольствием получит ответы и на основе конкретных сценариев использования.
РЕДАКТИРОВАТЬ: немного больше контекста. Скажем, у меня есть система управления книгами. Моя модель:
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.
}
Почему я хочу оставить только идентификатор, а не полноправного члена? Скажем, когда я получаю информацию о книге, мне редко нужно знать, кто ее пожертвовал или одолжил. Получение их полной информации для заполнения полей donatedBy и loanedBy является излишним.
Конечно, это только мои очки. Я уверен, что я скучаю по вещам, поэтому хотел знать, какие моменты в пользу / против.
Ответы:
В зависимости от вашей среды и проблемного контекста необходимость использования базы данных может быть уменьшена, и в результате (IMO) аргумент для использования только идентификаторов теряется.
Например, PHP Doctrine2 ORM имеет
EntityManager::getReference
лениво загруженный прокси для сущности, используя предоставленный идентификатор; Я не знаю, сколько других ORM делают это, но это примерно соответствует понятию «мини-класс», которое вы упоминаете. Для большинства целей и задач это полностью гидратированный объект, поэтому вы можете передать его и использовать как любой другой.Единственный случай, когда это не так, это когда ему дают недопустимый идентификатор, и в этом случае вы все равно захотите пойти в базу данных для проверки; Кроме того, чтобы снизить стоимость получения сущностей, большинство ORM имеют (в первом и втором уровнях) функции кэширования, доступные в той или иной форме.
Как только мы сократим необходимость и стоимость обращения к базе данных, у нас останется много преимуществ использования объекта в качестве параметра:
Конечно, есть случаи, когда кто-то может захотеть передать только идентификатор: например, при пересечении ограниченной границы контекста (говорят в дизайне, управляемом доменом). Если мы рассмотрим два ограниченных контекста с различными представлениями о том, что составляет учетную запись (например, финансы против отношений с клиентами), то мы не можем передать учетную запись контекста A в контекст B. Вместо этого идентификатор учетной записи (на языке домена) может пройти через
источник
Для такого рода вопросов я делегирую любое решение, наилучшим образом сообщающее о моих намерениях как программиста, и облегчающее работу «Будущего Грега».
Использование объекта в качестве аргументов облегчает получение правильного вызова метода через 6 месяцев, и я забыл о мельчайших деталях этого приложения. Для того, чтобы опираться на ваш «пример этой книги в списке пожеланий этого человека», предположим, что
isInWishList
метод действительно должен сравнивать только целочисленные идентификаторы книг и участников. В действительности этому методу нужны только две части данных, чтобы выполнить свою работу. Теперь давайте отступим от этого одного метода и рассмотрим всю систему программного обеспечения. Я сомневаюсь, что для работы требуется только идентификатор книги и идентификатор участника. Вы все равно будете извлекать всю книгу и член из базы данных еще до вызова,isInWishList
потому что, скорее всего, вам нужно будет сделать что-то большее, чем просто вызвать этот метод. Может быть, вы делаете, но в большинстве случаев вам нужно сделать больше.Учитывая это, вы не собираетесь реально снижать производительность, выбирая и отображая оба объекта полностью из базы данных. Теоретически вам потребуется меньше обращений к базе данных, но на практике вы обнаружите, что это просто неправда. Если вы передадите эти идентификаторы в качестве параметров в строке запроса обратно на сервер, то да, вам просто нужно получить список желаний из базы данных. Но это очень узкий взгляд на все ваше приложение. Будут сценарии, когда вы выполняете другие операции в дополнение к проверке списка пожеланий - например, добавление книги в список пожеланий. Вы не хотите добавлять дубликаты.
Выберите решение, которое проще всего понять новому программисту или вашему Future Self, а именно передать объекты
Book
иMember
. Только после обнаружения реальной проблемы с производительностью вы должны действительно позаботиться о простой передаче идентификаторов.Или мы могли бы вспомнить, что статически типизированные языки, такие как Java, предлагают перегрузку методов, так что вы можете получить свой торт и съесть его тоже:
Реальный ответ на этот вопрос - написать оба метода, вызвать целочисленную версию из строго типизированной версии, а Боб - твой дядя.
источник