2013-12-25 4 views
1

У меня вопрос о программной архитектуре. У меня часто возникает следующая проблема:Рекомендации по ленивой загрузке объектов с сервера

Предположим, у нас есть массив объектов на нашем сервере. Один объект состоит из краткого описания (назовем его description) и тяжелого fullData. У нас есть клиентское приложение, которое загружает список объектов только с description. И когда пользователь выбирает один элемент в списке, загружается fullData для этого элемента.

Обычно я реализую какой-то объект dataSource, который загружает список элементов с помощью descriptions. Но тогда мы должны получить fullData с сервера.

Обычно я делаю так: реализую метод, подобный fetchFullDataForObject(MyObject object) (псевдокод) в DataSource.

Проблема заключается в том, что в этом случае объекты становятся зависимыми от DataSource (если мы хотим получить доступ объекта, fullData, либо мы должны проверить, если это null и вызвать fetchFullData себя, или неявно называть его внутри объекта (в данном случае объект должен содержать ссылку на источник данных, к которому он принадлежит, я реализовал эту опцию в псевдокоде ниже)). В обоих случаях мы должны держать ссылку на dataSource. Другой вариант - сохранить код для извлечения fullData внутри класса Objects. Но в этом случае Object содержит логику взаимодействия клиент-сервер. Для меня это не похоже на хорошую практику.

Каковы наилучшие практики для таких ситуаций? Чья ответственность за загрузку fullData есть? Может быть, есть общий шаблон дизайна, который используется в таких случаях?

Я реализовал один из возможных вариантов ниже. Поскольку это не является специфическим (на мой взгляд) языком разработки, я написал его в псевдокоде.

//pseudocode 
class Object 
{ 
    private String description; 
    private Data fullData = null; 
    DataSource dataSource; 

    public Object(String description, DataSource dataSource) 
    { 
     this.description = description; 
     this.dataSource = dataSource; 
    } 

    public String getDescription() 
    { 
     return this.description; 
    } 

    public Data getFullData() 
    { 
     if (fullData == null) 
      this.dataSource.fetchFullDataForObject(this); //one of possible options 
     return fullData; 
    } 
}; 

class DataSource 
{ 
    private List<Object> objects = null; 
    private void loadItemsFromServer(); //loads objects (without fullData) and saves them to the "objects" list 

    public List<Object> getObjects() 
    { 
     if (objects == null) 
      loadItemsFromServer(); 
     return objects; 
    } 

    public void fetchFullDataForObject(Object object); 
}; 

ответ

1

Вы правы, что проведение ссылки из Object в dataSource не является хорошей практикой, потому что:

  • Ваш dataSource объект похож на Repository реализации шаблона.
  • Ваш Object похож на объект домена.

Лучше разделить систему доступа к данным и модель домена.

Итак, у вас есть следующие варианты:

  1. Вы можете извлечь IDataSource интерфейс и положить его в модели предметной области. И его реализация DataSource может быть в вашем Уровне доступа к данным.

  2. Вместо передачи экземпляра IDataSource/DataSource вы можете передать функцию (например, anonymous function).

  3. Вместо передачи экземпляра IDataSource/DataSource в конструктор можно передать экземпляр Data. Для реализации типа lazy load, полученного от Data, может использоваться (например, LazyData, который реализован при доступе к данным). Иногда тип LazyData реализован как decorator.

Эти ссылки могут быть полезны:

  1. Lazy Loading
  2. Four Ways to Implement Lazy Loading in C#
Смежные вопросы