2010-08-18 2 views
3

У меня есть понимание, что использование процедур доступа к данным непосредственно из кода представления считается злым. Поэтому у меня есть отдельный проект 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, по существу являющуюся тонкой оболочкой на последнем. Вероятно, может быть какая-то проверка или кэширование или тому подобное, но первое похоже, что в большинстве случаев оно просто переходит к последнему.

Я иду по этому правильному пути, или есть что-то, что мне не хватает?

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

EDIT: чтобы быть немного яснее, я не говорю о NHibernate или шаблоне хранилища, а о расслоении проблем.

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

ответ

4

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

  • РекомендоватьMovieToFriend (int movieID, строка friendEmail);
  • RateMovie (int movieID, int numberOfStars);
  • AddMovieToMyWishList (int movieID, int userID);

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

0

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

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

Имея класс обслуживания просто обернуть хранилище ИМО ненужный сложности.

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

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

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

0

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

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