Это хорошая практика, чтобы обернуть связанный набор свойств в свою собственную структуру / класс?

10

Написание объекта User в Swift, хотя мой вопрос касается любого строго типизированного языка. Пользователь может иметь несколько ссылок (FacebookProfile, InstagramProfile и т. Д.). Несколько вопросов по этому поводу.

  1. Это хорошая практика, чтобы обернуть ссылки в свой собственный объект?
    struct User {
       var firstName: строка
       var lastName: строка
       var email: string
       Вар ссылки: Ссылки
    }
    struct Links {
       var facebook: строка
       var instagram: строка
       var twitter: string 
    }

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

struct User { 
   var firstName: string
   var lastName: string
   var email: string
   var facebookLink: string
   var twitterLink: string
   var instagramLink: string
}
  1. В таком случае ссылки должны быть коллекцией / списком? Я полагал, что это не должен быть список, потому что есть фиксированное количество доступных вариантов ссылок, а не растущее число. Правильно ли мое мышление?

  2. Является ли хорошей практикой размещать мои сетевые методы внутри объекта User, такие как getUsers, getUser, updateUser?

Я знаю, что это может быть субъективно, но я пытаюсь понять, как лучше всего справляться с подобными ситуациями. Был бы признателен за любые указатели.

Прабху
источник

Ответы:

30

Вам либо понадобится

  • ноль вещей,
  • одно, или
  • произвольный номер вещи.

Я шокирован тем, что ваш дизайн предсказывает, что количество необходимых ссылок всегда будет равным трем, и что вы всегда будете знать, как их зовут.

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

Я бы чувствовал себя по-другому, если бы в этих ссылках было что-то особенное для них. Что-то особенное, что я делаю по-другому при доступе к ссылке на Facebook, но я не делаю это для ссылки в твиттере. Это сделало бы их разными. Но это не указано в этом коде.

Вот почему меня не беспокоит строка электронного письма. Я знаю, что используется по-другому, чем ссылки.

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

candied_orange
источник
4
FacebookProfile, InstagramProfile, ...Я думаю, что ОП уже ответил на вопрос. Его язык говорит нам, что пользователи могут не иметь ни одного, ни нескольких профилей, связанных с социальными сетями. Но программист внутри него превратил этот элемент в простые ссылки. Почему не коллекция Profiles? Я согласился с CandiedOrange. Вы слишком много думаете о будущем. Могут появиться новые социальные сети. Фактические могут исчезнуть. Пользователи могут переходить из одной сети в другую.
Laiv
Это догадки. Скажем, вы хотите использовать эти профили для социальных входов. Имея компонент Profile, у нас есть с чего начать. Где инкапсулировать информацию, касающуюся аутентификации и текущего сеанса с этими профилями. Это может рассматриваться как YAGNI или чрезмерное проектирование, но не стоит думать об этом, посмотреть, могут ли эти функции быть запрошены или могут ли они обеспечить ценность для нашего приложения. Если нет, просто откажитесь от них.
Laiv
1
@ Прабху зависит от того, почему вы ограничиваете это. Я думаю, что только многие из них вписываются в GUI. Что хорошо. Но не ограничивайте структуру данных из-за GUI. Графический интерфейс меняется по прихоти. Структуры данных являются дорогостоящими для изменения. Это действительно выгодно, чтобы понять их правильно с первого раза.
candied_orange
2
В этом-то и дело. Просто примите те структуры, которые сделают возможные будущие изменения менее болезненными. Не больше, не меньше. Мы, Кэнди и я говорим это, потому что мы (я верю) часто сталкивались с подобными ситуациями, и мы предвидим возможные особенности, которые могут изменяться или развиваться. В конечном счете, вы ближе к проекту и его будущей перспективе.
Laiv
1
@Prabhu: Обратите внимание, что вы задали вопрос о хорошей практике , а не о том, является ли это наиболее кратким подходом для вашего конкретного сценария. Я обычно на стороне избегания чрезмерного проектирования, но стоимость будущего обслуживания (добавление / удаление ссылок, обновление определений классов сущностей и т. Д.) Намного превышает стоимость реализации набора ссылок. Если вы назвали столбцы link1, link2, link3, потребность в коллекции была бы более очевидной. Однако тот факт, что вы дали столбцам более осмысленное имя, не меняет того факта, что это набор повторяющихся данных.
Флейтер
6

Вы находитесь на грани попадания в ловушку "Я вижу техническую возможность".

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

Все они в порядке, но в контексте пользовательского класса это что-нибудь значит? Нет. Это так же бессмысленно, как и подгруппа, использующая классы с именами «строки» и «числа».

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

Никто никогда не говорит о ссылках пользователя. Было бы иначе, если бы вы назвали свой агрегат SocialNetworkIds. Поскольку это действительно что-то значит, это будет истинное свойство пользователя, а не произвольная техническая коллекция.

Мартин Маат
источник
Именно мои сомнения заставили меня задать этот вопрос. Единственное отношение между различными ссылками заключается в том, что они могут отображаться вместе в пользовательском интерфейсе. Таким образом, в этом случае вы бы предложили НЕ помещать их в отдельный объект правильно, а вместо этого оставить их непосредственно под объектом User?
Прабху
1
Я не думаю, что это будет полезно в этом случае. У вас пока нет проблемы, которая оправдывает добавление слоя сложности. Если бы у вас было намного больше свойств, вы могли бы выиграть в группировке (с подходящими именами для групп). Трудно сказать, что подходит без контекста, хотя. Суть в том, что все должно быть проще. Чтобы понять и / или выполнить любой следующий шаг в процессе разработки.
Мартин Маат
Я вообще , как избежать чрезмерной техники, но я задаюсь вопросом : ты бы сказал то же самое , если ОП назвал свои поля link1, link2, link3? Дизайн структуры данных не зависит от имени полей, поэтому мой пример функционально эквивалентен. Это вопрос будущего. YAGNI обычно применяется, но в любом случае социальные сети оказались подвержены вирусной популярности и изменениям. Избегать перепланировки для каждого нового популярного сайта в социальных сетях кажется желательным. В противном случае вы рискуете попасть в «что еще одно поле?» ловушка, которая может создать огромный долг.
Флэттер
1

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

Я согласен с вашим мнением о # 2. Как упоминалось выше, если число будет расти или становиться переменным, список или другая коллекция будет хорошим выбором, но не для сценария, который вы описали.

Я не стал бы размещать сетевые методы внутри объектов, которые содержат данные, полученные сетью. Откуда поступили данные и как их получить, обычно не имеет отношения к основной цели класса. Что, если в будущем вы захотите получить данные с диска? Или хотите, чтобы пользователь ввел его? Пройдите достаточно далеко по этому пути, и простой Userкласс должен иметь код для обработки всех возможных методов ввода и извлечения данных. Просто Userдержите класс и сохраняйте данные, пока они находятся в памяти. Все остальное может быть обработано более подходящими классами.

user1118321
источник