Что плохого в возвращении хеш-таблицы из открытого метода и когда имеет смысл это делать?

9

Каковы проблемы проектирования при возврате хеш-таблицы из открытого метода, когда вы хотите вернуть несколько элементов вместо создания класса и возврата объекта этого?

Если у него есть проблемы, то при каких обстоятельствах имеет смысл это делать?

Как меняется ответ на этот вопрос в зависимости от того, является ли язык динамичным или нет?

Редактировать: чтобы уточнить, что ключи будут постоянными и являются частью кода, а не данных. То, для чего мы обычно создаем класс. Вопрос в том, почему было бы неправильно использовать хеш-таблицу вместо этого, если создание класса действительно кажется правильным выбором.

Мухаммед Хасан Хан
источник

Ответы:

11

Используйте лучше определенный класс в качестве возвращаемого типа, чем хеш-таблицу, которая содержит произвольное количество значений в качестве пар имя / значение.

  1. Первый и самый важный момент - ремонтопригодность. Глядя на код, новый программист никогда не сможет сказать, какие значения возвращает метод. Если новый человек не понимает этого, глядя на код, код не будет полезен и подвержен ошибкам, когда кто-то собирается добавить больше ключей / значений к этим данным или улучшить приложение.

  2. Методы - это контракты между абонентом и сервисом. Самым важным в методе является их ввод и вывод. Этот ввод и вывод должен быть легко читаемым и понятным и самодокументируемым. Если вы используете класс Person в качестве возвращаемого значения, которое имеет имя, фамилию, возраст - это самодокументирование. Если вы сгенерируете Javadoc для этого, пользователь может перемещаться между классами, чтобы лучше это понять. Если вы используете хеш-таблицу, вы должны либо объяснить это в комментариях, которые никто не будет читать, либо обновлять, когда что-то изменится.

  3. Вы не можете использовать дженерики, как HashMap<String,String>в случае, если вы хотите добавить число (скажем, возраст) в оператор возврата. Если вы не используете дженерики, вам придется переходить от объекта к фактическому типу. Вы можете сохранить это, если вы используете динамическую типизацию.

  4. Также больше шансов сбоя во время выполнения, чем при обнаружении проблем во время компиляции. например, если кто-то удаляет запись из хэш-карты, и один из старых абонентов ожидает эту запись, клиент завершает работу во время выполнения. Всегда лучше уловить эту проблему во время компиляции.

  5. Будет трудно вернуть неизменный тип, если вы хотите использовать hashmap в качестве возвращаемого типа и так далее. Но если вы используете определенный пользователем тип, вы можете контролировать это.

Будет заманчиво использовать hashmap в качестве возвращаемого типа, потому что вы можете избежать создания пары классов в начале, но это будет кошмаром для поддержки кода в будущем. Иди объектно-ориентированный !!!!

java_mouse
источник
1
Вы, кажется, правильно поняли вопрос. Спасибо.
Мухаммед Хасан Хан
8

Одна из проблем заключается в том, что во многих случаях ключом для хэш-таблицы будет строка. Таким образом, потребители метода должны знать заранее, какие ключи использовать для извлечения данных. Это может привести к ошибкам из-за неправильного ввода данных при доступе к данным.

Еще один недостаток - рефакторируемость. Если позже вы решите изменить имя члена, у вас будет куча волшебных строк, которые также нужно изменить. Намного проще переименовать члена класса, используя инструменты рефакторинга, предоставляемые большинством хороших IDE. С хеш-таблицей вам, вероятно, придется выполнить операцию поиска / замены для всех исходных файлов, что может быть проблематично.

Наконец, вы потеряете проверку времени компиляции доступа члена - как с точки зрения имени, так и типа. Последнее не является такой проблемой, если ваша хеш-таблица содержит только один тип объекта, но если в нем много (даже в одной и той же иерархической цепочке), вы действительно хотите использовать систему типов вашего языка и проверить там время компиляции. В большинстве IDE у вас есть какие-то функции intellisense / autocomplete - они работают, глядя на систему типов, но не смогут помочь вам с ключами хеш-таблицы.

Что касается случаев, когда было бы целесообразно возвращать хеш-таблицу (или другую подобную коллекцию пар ключ-значение), вы использовали бы это, когда и значения, и ключи не известны во время компиляции. Например, если у вас есть метод, который анализирует строку запроса и возвращает ключи и соответствующие значения, хеш-таблица будет хорошим выбором. В этом случае вам также стоит подумать о возвращении какой-нибудь неизменяемой или только для чтения хеш-таблицы.

Редактировать - большинство вопросов, поднятых в этом ответе, перестают применяться, когда вы говорите о динамических языках :)

MattDavey
источник
Что если язык динамический?
Мухаммед Хасан Хан
Я не специалист по динамическим языкам, поэтому кто-то другой может дать лучший ответ на этот вопрос. Но я знаю, что динамические языки в любом случае не проверяют время компиляции. Но в этом случае возврат объекта и возвращение хеш-таблицы не так уж отличаются ...
MattDavey
3
@ Хасан Хан: В этом случае на самом деле не может быть никакой разницы между хеш-таблицей и экземпляром класса. Например, в Javascript все объекты являются хеш-таблицами, а object.property - это то же самое, что object ['property']
Майкл Боргвардт,
«С хэш-таблицей вам, вероятно, придется выполнять операцию поиска / замены для всех исходных файлов, что может быть проблематично». Только если вы выбрали плохие ключи и никогда не пытались выделить стандартные, чтобы они были определены в одном месте ...
Донал Феллоуз
7

Наиболее важным аргументом против этого будет то, что вы предоставляете слишком много информации потребителю. Потребляющему коду нужно только знать, что это какой-то набор значений ключей (словарь); Реализовано ли это как хэш-карта, список ассоциаций, три или что-то еще, относительно неинтересно. Таким образом, правильным способом будет возврат через подходящий интерфейс ( IDictionaryили любой другой язык, который вы предпочитаете) вместо реального типа.

Все это при условии, что вам действительно нужен словарь для представления ваших данных, то есть ваши данные состоят из пар ключ / значение, где ключи уникальны среди набора данных и не могут быть исправлены во время компиляции. Если у вас есть заранее известные ключи, вы должны создать правильный тип (или несколько, как требуется) для ваших данных. Все сводится к тому, считаете ли вы сами ключи частью данных или частью кода.

РЕДАКТИРОВАТЬ :

Чтобы уточнить, я использую термин словарь для обозначения наиболее общего типа структуры данных ключ-значение здесь; Я не имею в виду какую-либо языковую реализацию, такую ​​как Python dictили .NET Dictionary.

tdammers
источник
1
+1 за «Все сводится к тому, считаете ли вы сами ключи частью данных или частью кода». - Это хороший способ выразить это. Не уверен, насколько универсален термин «словарь» в отличие от «карты», например.
MattDavey
Возвращение словаря не было предназначено. ключи были частью кода, а не данных.
Мухаммед Хасан Хан
Настоящий вопрос заключается в аргументации «Вы должны создавать правильный тип». Вопрос почему?
Мухаммед Хасан Хан
2

Один вопрос, который я хотел бы задать себе: «меняются ли ключи в этом словаре?» Если они постоянны, вы должны вернуть объект или другую подходящую структуру данных. Если они динамические, вы можете захотеть вернуть некую структуру словарного стиля. Наконец, если есть некоторые ключи, которые будут постоянными, и некоторый неизвестный набор динамических ключей, вы можете вернуть гибридную структуру данных, включающую в себя некоторые фиксированные значения и некоторый словарь для переполнения.

Уайетт Барнетт
источник
Действительно, ваш совет верен, но вопрос в том, что не так с выбором использования хэш-таблицы, когда класс является лучшим выбором.
Мухаммед Хасан Хан
Это не или / или; класс может легко содержать словарь, если вам это нужно.
Уайетт Барнетт