210

OOP デザイン パターンで、リポジトリ パターンとサービス層の違いは何ですか?

私はASP.NET MVC 3アプリに取り組んでおり、これらのデザインパターンを理解しようとしていますが、私の脳はまだそれを理解していません.!!

4

5 に答える 5

352

リポジトリ レイヤーは、データ アクセスに対する追加の抽象化レベルを提供します。書く代わりに

var context = new DatabaseContext();
return CreateObjectQuery<Type>().Where(t => t.ID == param).First();

データベースから単一のアイテムを取得するには、リポジトリ インターフェイスを使用します

public interface IRepository<T>
{
    IQueryable<T> List();
    bool Create(T item);
    bool Delete(int id);
    T Get(int id);
    bool SaveChanges();
}

と呼び出しますGet(id)。リポジトリ レイヤーは、基本的なCRUD操作を公開します。

サービス層は、リポジトリを使用するビジネス ロジックを公開します。サービスの例は次のようになります。

public interface IUserService
{
    User GetByUserName(string userName);
    string GetUserNameByEmail(string email);
    bool EditBasicUserData(User user);
    User GetUserByID(int id);
    bool DeleteUser(int id);
    IQueryable<User> ListUsers();
    bool ChangePassword(string userName, string newPassword);
    bool SendPasswordReminder(string userName);
    bool RegisterNewUser(RegisterNewUserModel model);
}

List()リポジトリのメソッドはすべてのユーザーを返しますが、ListUsers()IUserService のメソッドは、ユーザーがアクセスできるユーザーのみを返すことができます。

ASP.NET MVC + EF + SQL SERVER では、次のような通信の流れがあります。

ビュー <- コントローラー -> サービス レイヤー -> リポジトリ レイヤー -> EF -> SQL Server

サービス層→リポジトリ層→EFモデル上で動作する部分です。

ビュー ← コントローラ -> サービス層この部分はビューモデル上で動作します。

編集:

/Orders/ByClient/5 のフローの例 (特定のクライアントの注文を確認したい):

public class OrderController
{
    private IOrderService _orderService;

    public OrderController(IOrderService orderService)
    {
        _orderService = orderService; // injected by IOC container
    }

    public ActionResult ByClient(int id)
    {
        var model = _orderService.GetByClient(id);
        return View(model); 
    }
}

これは注文サービスのインターフェースです:

public interface IOrderService
{
    OrdersByClientViewModel GetByClient(int id);
}

このインターフェイスはビュー モデルを返します。

public class OrdersByClientViewModel
{
     CientViewModel Client { get; set; } //instead of ClientView, in simple project EF Client class could be used
     IEnumerable<OrderViewModel> Orders { get; set; }
}

これはインターフェースの実装です。モデル クラスとリポジトリを使用してビュー モデルを作成します。

public class OrderService : IOrderService
{
     IRepository<Client> _clientRepository;
     public OrderService(IRepository<Client> clientRepository)
     {
         _clientRepository = clientRepository; //injected
     }

     public OrdersByClientViewModel GetByClient(int id)
     {
         return _clientRepository.Get(id).Select(c => 
             new OrdersByClientViewModel 
             {
                 Cient = new ClientViewModel { ...init with values from c...}
                 Orders = c.Orders.Select(o => new OrderViewModel { ...init with values from o...}     
             }
         );
     }
}
于 2011-02-19T07:16:45.983 に答える
47

Carnotaurus が言ったように、リポジトリはストレージ形式からビジネス オブジェクトにデータをマッピングする責任があります。ストレージとの間でデータを読み書きする方法(削除、更新も)の両方を処理する必要があります。

一方、サービス層の目的は、ビジネス ロジックを 1 つの場所にカプセル化して、コードの再利用と関心の分離を促進することです。Asp.net MVC サイトを構築するときにこれが実際に意味することは、私がこの構造を持っているということです。

[コントローラー] が [リポジトリ] を呼び出す [サービス] を呼び出す

私が有用だと思った原則の 1 つは、コントローラーとリポジトリーのロジックを最小限に抑えることです。

コントローラーでは、それが私を DRY に保つのに役立つからです。同じフィルタリングまたはロジックを別の場所で使用する必要があり、コントローラーに配置した場合、再利用できないことはよくあります。

リポジトリでは、より良いものが登場したときにストレージ (または ORM) を交換できるようにしたいためです。また、リポジトリにロジックがある場合、リポジトリを変更するときにこのロジックを書き直す必要があります。リポジトリが IQueryable のみを返し、サービスがフィルタリングを行う場合、マッピングを置き換えるだけで済みます。

たとえば、最近、Linq-To-Sql リポジトリのいくつかを EF4 に置き換えましたが、この原則に忠実であったリポジトリは数分で置き換えることができました。私がある程度の論理を持っていた場合、それは代わりに数時間の問題でした.

于 2011-02-19T07:28:25.040 に答える
8

通常、リポジトリは、エンティティを設定するための足場として使用されます。サービス レイヤーが出て、リクエストを送信します。サービス層の下にリポジトリを配置する可能性があります。

于 2011-02-19T06:59:47.580 に答える
6

リポジトリ レイヤーは、データベースにアクセスするために実装され、データベースでの CRUD 操作を拡張するのに役立ちます。一方、サービス層はアプリケーションのビジネス ロジックで構成され、リポジトリ層を使用してデータベースに関連する特定のロジックを実装する場合があります。アプリケーションでは、リポジトリ レイヤーとサービス レイヤーを分けた方がよいでしょう。リポジトリとサービス レイヤーを分離することで、コードがよりモジュール化され、データベースがビジネス ロジックから分離されます。

于 2018-09-30T15:46:17.047 に答える