Должен ли класс обслуживания быть больше, чем оболочка класса репозитория? - PullRequest
5 голосов
/ 18 августа 2010

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

У меня довольно простой домен, просто класс Movie.Соответствующий интерфейс репозитория:

public interface IMovieRepository
{
    void AddMovie(Movie movie);
    void UpdateMovie(Movie movie);
    void RemoveMovie(Movie movie);
    int GetMovieCount();
    Movie GetMovieById(int id);
    IEnumerable<Movie> GetAllMovies();
    IEnumerable<Movie> GetMoviesByGenre(Genre genre);
    IEnumerable<Movie> GetMoviesByYear(int year);
    IEnumerable<Movie> GetMoviesByActor(string actor);
    IEnumerable<Movie> GetMoviesByTitle(string title);
}

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

public interface IMovieService
{
    Movie CreateMovie(string title, int year, Genre genre, int length, IEnumerable<string> actors);
    void UpdateMovie(Movie movie);
    void RemoveMovie(Movie movie);
    int GetMovieCount();
    Movie GetMovieById(int id);
    IEnumerable<Movie> GetAllMovies();
    IEnumerable<Movie> GetMoviesByGenre(Genre genre);
    IEnumerable<Movie> GetMoviesByYear(int year);
    IEnumerable<Movie> GetMoviesByActor(string actor);
    IEnumerable<Movie> GetMoviesByTitle(string title);
}

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

Правильно ли я поступаю по этому поводу, или есть что-то, что я 'м отсутствует?

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

РЕДАКТИРОВАТЬ: чтобы быть немного яснее, я не говорю о NHibernate или шаблон хранилища, а скорее о распределении проблем.

ОБНОВЛЕНИЕ: спасибо, ребята.Я полагаю, что я оставлю конкретные методы запросов в классе обслуживания, которые будут простыми для уровня пользовательского интерфейса, и попытаюсь обобщить некоторые из репозиториев, передав запросы в функцию запроса.

Ответы [ 4 ]

4 голосов
/ 18 августа 2010

Я думаю, что вы на правильном пути. Причина, по которой ваши DataAccess API и ServiceAPI выглядят так схоже, заключается в том, что вы еще не предоставили своей услуге настоящую бизнес-логику. Вот несколько мозговых штурмов, которые могут в конечном итоге возникнуть в вашем сервисном API, но могут включать в себя некоторые более сложные операции, чем простая функциональность CRUD (создание, чтение, обновление, удаление). Очевидно, это просто быстрые и грязные примеры, но я уверен, что вы поняли:

  • RecomMovieToFriend (int movieID, строка friendEmail);
  • RateMovie (int movieID, int numberOfStars);
  • AddMovieToMyWishList (int movieID, int userID);

Я думаю, что разделение ServiceLayer и DataLayer является важным и ценным, и вам не следует об этом догадываться, даже несмотря на то, что два API в настоящее время очень похожи. По мере роста функциональности вашего сервиса эти два API будут продолжать расходиться, чтобы удовлетворить потребности своих абонентов.

1 голос
/ 18 августа 2010

Наличие класса Service для простого переноса хранилища - это ненужная сложность IMO.

Я обычно заканчиваю тем, что использую методы bool Try ... (TrySave, TryDelete и т. Д.) В слое Service (если у меня естьлюбой), а затем добавить сообщения об ошибках в качестве выходных параметров.Я только позволяю репозиториям обрабатывать проблемы с постоянством - входить и выходить из репозитория.

Что касается запросов - я не позволяю это через мой Сервис, если у меня нет сложных объектов-фильтров, ориентированных на пользовательский интерфейс, которые необходимо«переведено», прежде чем они попадут в репозиторий.

Надеюсь, это поможет!

1 голос
/ 18 августа 2010

Мне обычно нравится размещать более сложные запросы в моих классах обслуживания.Те, которые вызывают какой-либо метод репозитория, а затем используют дополнительные методы Linq to Object для получения желаемого набора данных.

0 голосов
/ 18 августа 2010

Учитывая интерфейс IMovieRepository, как вы его определили, интерфейс IMovieService является избыточным.Если интерфейс репозитория был универсальным, как указано ниже, тогда существует значение для интерфейса службы.Я предпочитаю более простой интерфейс репозитория, потому что для меня он обеспечивает лучшее разделение задач

public interface IRepository<T> {
    IQueryable<T> Fetch();
    void Save(T item);
    void Remove(T item);
}
...