Полезно ли определять, какие данные загружать в контроллер? - PullRequest
1 голос
/ 17 мая 2009

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

Например, с учетом этой сущности:

public class Category
{
     public int id;
     public Category child;
     public Category parent;
}

В представлении «ShowChild» вы не хотите загружать свойство «parent», поскольку оно не отображается.

Итак, с учетом этого сценария я реализовал очень хорошую «систему» ​​в своем хранилище для загрузки сущностей из БД, заполняющих только те свойства, которые я хочу. Это работает так:

Категория категории = repo.FindCategory (id, (int) (LoadLevel.basic | LoadLevel.Child))

Так что теперь у меня есть экземпляр категории с загруженными только свойствами id и Child.

Дилемма, с которой я здесь сталкиваюсь, заключается в том, что если я определю LoadLevel в моем слое serviceLayer (где он должен быть), мне придется написать два метода, «LoadCategoryWithChild» и «LoadCategoryWithParent», по одному на каждый класс обслуживания. вид (СУХОЕ нарушение?).

public class CategoryService
{
     public Category LoadCategoryWithChild(int id)
     {
         int loadlevel = (int) (LoadLevel.Basic | LoadLevel.Child);
         return repo.FindCategory(id, loadlevel);
     }
}

ИЛИ, другой вариант, который я вижу, это определить уровень загрузки в контроллере (нарушение MVC?) И реализовать только один метод в моем классе обслуживания:

public class CategoryService
{
     public Category LoadCategory(int id, int loadlevel)
     {
         return repo.FindCategory(id, loadlevel);
     }
}

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

Ответы [ 3 ]

1 голос
/ 18 мая 2009

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

Я бы изменил второй параметр, чтобы он не был int, хотя и был бы типом enum, чтобы вызывающая сторона знала, какие допустимые опции

0 голосов
/ 18 мая 2009

Я предлагаю:

public Category LoadCategory(int id, params LoadLevel[] levels)
{
    int loadLevel = LoadLevel.Basic;

    foreach (var level in levels)
        loadLevel = loadLevel | level;

    return repo.FindCategory(id, loadlevel);
}

Пример использования:

LoadCategory(0, LoadLevel.Parent, LoadLevel.Child); // self + parent+ child
LoadCategory(1, LoadLevel.Child); // self + child
LoadCategory(2); // self only
0 голосов
/ 17 мая 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...