1

Я ищу несколько советов по архитектуре для решения клиент/сервер с некоторыми особенностями.Защита конфиденциальных данных сущности

Клиент довольно толстый, оставляя сервер главным образом для обеспечения жизнеспособности, параллелизма и инфраструктуры. Сервер содержит несколько объектов, которые содержат как конфиденциальную, так и общедоступную информацию. Подумайте, например, что лица являются лицами, предположим, что номер и имя социального страхования чувствительны, а возраст является общедоступным.

При запуске клиента пользователю предоставляется ряд объектов, не раскрывающих конфиденциальной информации. В любое время пользователь может выбрать вход в систему и аутентификацию с сервером, поскольку аутентификация прошла успешно, пользователю предоставляется доступ к конфиденциальной информации.

Клиент имеет доменную модель, и я думал о ее реализации как о какой-то «ленивой загрузке», сделав первый запрос, создающий объекты, а затем обновляя их конфиденциальными данными. Газопоглотители сущностей будут бросать исключения на конфиденциальной информации, когда они не были раскрыты, f.e .:

class PersonImpl : PersonEntity 
{ 
    private bool undisclosed; 

    public override string SocialSecurityNumber { 
     get { 
      if (undisclosed) 
       throw new UndisclosedDataException(); 

      return base.SocialSecurityNumber; 
     } 
    } 
} 

Еще более дружественным подходом может быть иметь значение объекта, указывающий, что значение не указано.

get { 
    if (undisclosed) 
     return undisclosedValue; 

    return base.SocialSecurityNumber; 
} 

Некоторые проблемы:

  • Что делать, если пользователь входит в систему, а затем из, чувствительные данные были загружены, но должны быть раскрыты еще раз.
  • Можно утверждать, что этот тип функциональности относится к домену, а не к некоторой инфраструктурной реализации (т. Е. Реализации репозитория).
  • Как всегда при работе с большим количеством свойств, есть риск того, что этот тип функциональности загромождает код

Любые идеи или обсуждения оценили!

ответ

2

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

Так как и почему это применимо? На самом деле у вас могут быть две разные модели представлений. Один для аутентификации и один для пользователей, не прошедших проверку подлинности. Вы публикуете фактические значения для конфиденциальных данных в модели с проверкой подлинности, а не для неаутентифицированной. Вы могли бы получить их из общего интерфейса, а затем код вместо интерфейса вместо типа объекта. Для вашей конкретной реализации пользователя, не прошедшего проверку подлинности, вы можете просто заполнить нечувствительные данные, в результате чего чувствительные геттеры будут делать то, что вы хотите, чтобы они делали.

Моего мнение на пару пунктов:

  • Я не поклонник отложенной загрузки в сущностях. Ленивая загрузка - это ответственность за доступ к данным, а не часть модели.Для меня это первоклассный участник того, что я решительно избегаю в своей области, а также подкачки и сортировка. Что касается того, как связать эти элементы вместе, я предпочитаю свободно связывать объекты с помощью указателей ID с другими объектами. Если мне нужны/нужны данные, содержащиеся в одном из этих объектов, я могу загрузить его. Это вроде как ленивая загрузка в некотором смысле, но я утверждаю, что это никогда не происходит в самой модели домена, делая это.
  • Я не поклонник бросать исключения на геттеры. Сетчатеры, с другой стороны, в порядке. Я смотрю на это с другой стороны. Предприятие должно всегда находиться в правильном состоянии. Getters не повлияет на состояние объекта - сеттеры. Выбрасывание сеттера обеспечивает целостность модели. Использование подхода с двумя представлениями модели позволило бы мне перевести логику на ведущего. Поэтому я мог бы в принципе сделать что-то вроде «если пользователь имеет тип несанкционированного доступа, сделайте это, иначе сделайте что-нибудь еще». Поскольку то, о чем вы говорите, в конечном итоге было бы примером того, как данные будут представлены пользователю и не важно для модели, я думаю, что это хорошо подходит. В общем, я использую типы с нулевым значением для своих свойств, которые могут быть нулевыми и не налагают ничего на геттеры, так как обычно это не часть его ответственности. Вместо этого я использую роли, чтобы определить, какую модель просмотра использовать.

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

Однако вы можете использовать что-то похожее на AutoMapper (в зависимости от вашей платформы), чтобы помочь в заполнении модели вашего представления от ваших объектов.

0

Я сделал ошибку, поставив вопрос, не создавая OpenId, поэтому мне кажется, что мне нужно будет прокомментировать здесь (?).

Прежде всего, спасибо, что нашли время ответить - это, безусловно, имеет больше общего с представлением данных, чем то, как работает модель. Тем не менее, я чувствую необходимость прояснить некоторые вещи. Модель домена/сущности никогда не ссылаются непосредственно из пользовательского интерфейса. Я использую вариант шаблона DM-V-VM для разделения пользовательского интерфейса/бизнес-модели. Для ленивой загрузки и реализации репозитория в целом у меня есть реализации объектов на уровне инфраструктуры, где обрабатываются такие вещи, как сериализация, грязное отслеживание и ленивая загрузка.

Так слой домена имеет объекты, как:

class Entity { 
    virtual string SocialSecurityNumber { get; } 
} 

И слой инфраструктуры добавляет некоторые другие функциональные возможности, чтобы иметь возможность обновлять и восстанавливать entites с сервера:

class EntityImpl : Entity { 
    bool isDirty; 
    bool isLoaded; 
    // Provide the means to set value on deserialization 
    override string SocialSecurityNumber; 
} 

Так ленивая загрузка поведение будет реализовано на уровне инфраструктуры и никогда не будет видно на уровне домена.

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

Смежные вопросы