![](/img/trans.png)
[英]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.