[英]Concrete class implements an interface which knows the concrete class that implement it
[英]Is there a name for this design pattern where a concrete class implements a specific interface which implements a base interface for CRUD operations?
我試圖把它變成一個“通用”問題,因為我在 Java 和 C# 中看到過這個問題,我假設它也在其他 OO 語言中。
我知道訪問數據並執行CRUD操作的應用程序有三個“主要”框架:
在查看使用這三種設計模式之一的應用程序的教程和示例時,大多數(如果不是全部)執行以下操作:
BaseRepositoryInterface (我有時將其視為接口,有時將其視為抽象類)
interface BaseRepositoryInterface {
findOne(integer id);
findAll();
create();
read(integer id);
update(integer id);
delete(integer id);
}
特定存儲庫接口
interface SpecificRepositoryInterface implements BaseRepositoryInterface {
// Just Some Examples
specificActionNumberOne(integer id, String someString);
specificActionNumberTwo(integer id, Object someObject);
specificActionNumberThree(integer id, double someDouble);
}
具體存儲庫類
class ConcreteRepositoryClass implements SpecificRepositoryInterface {
Dao myDao;
// or
Dto myDto;
ConcreteRepositoryClass(Dao someDao)
// or
ConcreteRepositoryClass(Dto someDto)
{
this.myDao = someDao;
// or
this.myDto = someDto;
}
findOne(integer id){
// implement here ...
}
findAll(){
// implement here ...
}
create(){
// implement here ...
}
read(integer id){
// implement here ...
}
update(integer id){
// implement here ...
}
delete(integer id){
// implement here ...
}
specificActionNumberOne(integer id, String someString){
// implement here ...
}
specificActionNumberTwo(integer id, Object someObject){
// implement here ...
}
specificActionNumberThree(integer id, double someDouble){
// implement here ...
}
}
這在所有示例中並不總是完全相同,但它們都傾向於遵循相同的格式。
鑒於此,這種設計模式有名字嗎?
假設我正在尋找名稱的這種模式是上述框架的“演示者”、“控制器”或“視圖模型”部分,只是進一步抽象,是否安全?
對我來說,這是存儲庫模式。 在大多數情況下,這是在模型后面或連接到模型。 從存儲庫中,您可以為您提到的所有這些模式提供數據以進行建模。 模型可以直接存儲在存儲庫中,也可以轉換為一些 DTO 后存儲。 存儲庫通常由接口表示,以便在沒有真正連接到持久層的情況下進行測試。
我們有一個通用存儲庫模式,也有一個特定的存儲庫模式。 兩者都是正確的,各有利弊。
用於在 C# 中實現存儲庫模式:
public interface ICustomerRepository
{
IEnumerable GetCustomers();
Customer GetCustomerByID(int customerId);
void InsertCustomer(Customer customer);
void DeleteCustomer(int customerId);
void UpdateCustomer(Customer customer);
void Save();
}
上述接口與 EF 的實現如下所示:
public class CustomerRepository:ICustomerRepository
{
private ApplicationContext context;
public CustomerRepository(ApplicationContext context)
{
this.context = context;
}
public IEnumerable<Customer> GetCustomers()
{
return context.Customers.ToList();
}
public Customer GetCustomerByID(int customerId)
{
return context.Customers.Find(customerId);
}
public void InsertCustomer(Customer customer)
{
context.Customers.Add(customer);
}
public void DeleteCustomer(int customerId)
{
Customer customer = context.Customers.Find(customerId);
context.Customers.Remove(customer);
}
public void UpdateCustomer(Customer customer)
{
context.Entry(customer).State = EntityState.Modified;
}
public void Save()
{
context.SaveChanges();
}
}
就是這樣!
現在在 C# 中實現通用存儲庫模式
首先,為通用存儲庫創建一個接口
public interface IRepository<TEntity> where TEntity :class
{
void Delete(TEntity entityToDelete);
void Delete(object id);
IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "");
TEntity GetByID(object id);
IEnumerable<TEntity> GetWithRawSql(string query,
params object[] parameters);
void Insert(TEntity entity);
void Update(TEntity entityToUpdate);
}
然后上述接口與 EF 的實現如下所示:
class BaseRepository<TEntity> : IRepository <TEntity> where TEntity : class
{
internal ApplicationContext context;
internal DbSet<TEntity> dbSet;
public BaseRepository(ApplicationContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> GetWithRawSql(string query,
params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
if (includeProperties != null)
{
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
關於存儲庫的更多信息(工作單元模式 C#):
工作單元模式 C#
為單個事務使用單獨的存儲庫可能會導致部分更新。 例如,假設您必須更新兩個不同的實體類型作為同一事務的一部分。 如果每個都使用單獨的數據庫上下文實例,一個可能成功,另一個可能失敗,確保所有存儲庫使用相同數據庫上下文(從而協調所有更新)的一種方法是使用工作單元類。
public interface IUnitOfWork
{
IRepository<Customer> Customers { get; }
IRepository<Order> Orders { get; }
void Commit();
}
下面是上面 IUnitOfWork 的實現方式的代碼,
public class UnitOfWork : IUnitOfWork
{
private ApplicationContext _dbContext;
private BaseRepository<Customer> _customers;
private BaseRepository<Order> _orders;
public UnitOfWork(ApplicationContext dbContext)
{
_dbContext = dbContext;
}
public IRepository<Customer> Customers
{
get
{
return _customers ??
(_customers=new BaseRepository<Customer>(_dbContext));
}
}
public IRepository<Order> Orders
{
get
{
return _orders ??
(_orders=new BaseRepository<Order>(_dbContext));
}
}
public void Commit()
{
_dbContext.SaveChanges();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.