EF架构~引入规约(Specification)模式,让程序扩展性更强

简介:

规约(Specification)模式:第一次看到这东西是在microsoft NLayer项目中,它是微软对DDD的解说,就像petshop告诉了我们MVC如何使用一样,这个规约模式最重要的作用是实现了查询语句与查询条件的分离,查询语句在底层是稳定的,不变的,而查询条件是和具体业务,具体领域有关的,是易变的,如果我们为每一个领域的每一个新需求都写一个新的方法,那就会出现很多重复的代码,不利于程序的最终扩展!

下面我们来看一个经典例子

一个IOrderRepository的接口,定义了一个订单仓储

        Order_Info GetOrder_InfoById(int orderID);
        List<Order_Info> GetOrder_Info(DateTime from, DateTime to);
        List<Order_Info> GetOrder_InfoByUser(int userID);


代码本身没有任何问题,你只要去实现它就可以了,当一个新的需求到了之后,你的接口要被扩展(这是不被提倡的,一般我们会新建一个接口),然后修改

原来的实现类,去实现接口新的方法(违背了OCP原则),这种做法是大多部开发团队所经历了,我,一个普通的人,也经历了,但当我知道DDD后,当我看完

microsoft Nlayer项目之后,我知道,我一定要改变这种局面,于是,代码在规约模式的指导下,进行重构了,呵呵。

先看一下规约模式的类关系图

下面是我对原来结构的修改(由于原程序是三层架构,所以我就不改变原有架构了,只是对代码进行重构,DAL层,BLL层,WEB层)

DAL层

IRepository仓储接口如下,怎么去实现就不放了,呵呵

public interface IRepository<TEntity>
         where TEntity : class
    {
        /// <summary>
        /// 添加实体并提交到数据服务器
        /// </summary>
        /// <param name="item">Item to add to repository</param>
        void Add(TEntity item);

        /// <summary>
        /// 移除实体并提交到数据服务器
        /// 如果表存在约束,需要先删除子表信息
        /// </summary>
        /// <param name="item">Item to delete</param>
        void Remove(TEntity item);

        /// <summary>
        /// 修改实体并提交到数据服务器
        /// </summary>
        /// <param name="item"></param>
        void Modify(TEntity item);

        /// <summary>
        /// 通过指定规约,得到实体对象
        /// </summary>
        /// <param name="specification"></param>
        /// <returns></returns>
        TEntity GetEntity(ISpecification<TEntity> specification);

        /// <summary>
        /// 通用表达式树,得到实体
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        TEntity GetEntity(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Get all elements of type {T} in repository
        /// </summary>
        /// <returns>List of selected elements</returns>
        IQueryable<TEntity> GetEntities();

        /// <summary>
        /// Get all elements of type {T} that matching a
        /// Specification <paramref name="specification"/>
        /// </summary>
        /// <param name="specification">Specification that result meet</param>
        /// <returns></returns>
        IQueryable<TEntity> GetEntities(ISpecification<TEntity> specification);

        /// <summary>
        /// 通用表达式树,得到集合
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        IQueryable<TEntity> GetEntities(Expression<Func<TEntity, bool>> predicate);
    }

IOrderRepository接口如下

 public interface IOrderRepository :
        Domain.Core.IRepository<Order_Info>
    {
        void InsertOrder(Order_Info entity);
    }

DAL底层为数据持久化层,它是非常稳定的,只提供最基本的表操作,具体业务如何组成,全放在BLL层去实现

BLL层

这一层中定义具体业务的规约,并组成查询方法及调用DAL层的具体方法(DAL层来接受从BLL层传过来的ISpecification参数)

    /// <summary>
    /// 根据下单日期得到订单列表
    /// </summary>
    public class OrderFromDateSpecification : Specification<Order_Info>
    {
        DateTime? _fromDate;
        DateTime? _toDate;
        public OrderFromDateSpecification(DateTime? fromDate, DateTime? toDate)
        {
            _fromDate = fromDate ?? DateTime.MinValue;
            _toDate = toDate ?? DateTime.MaxValue;
        }
        public override global::System.Linq.Expressions.Expression<Func<Order_Info, bool>> SatisfiedBy()
        {
            Specification<Order_Info> spec = new TrueSpecification<Order_Info>();
            spec &= new DirectSpecification<Order_Info>(o => o.CreateDate >= _fromDate
                && o.CreateDate <= _toDate);
            return spec.SatisfiedBy();
        }
    }
    /// <summary>
    /// 通过用户信息得到他的订单列表
    /// </summary>
    public class OrderFromUserSpecification : Specification<Order_Info>
    {
        int _userID = default(Int32);
        public OrderFromUserSpecification(int userID)
        {
            _userID = userID;
        }
        public override global::System.Linq.Expressions.Expression<Func<Order_Info, bool>> SatisfiedBy()
        {
            Specification<Order_Info> spec = new TrueSpecification<Order_Info>();
            spec &= new DirectSpecification<Order_Info>(o => o.UserID == _userID);
            return spec.SatisfiedBy();
        }
    }

业务层真实的查询主体,只要在一个方法里写就OK了,然后它非常稳定,如果以后还有其它查询业务出来,直接添加一个查询规约即可

        /// <summary>
        /// 根据WEB层传来及组件好的规约,返回集体
         /// </summary>
        /// <param name="spec"></param>
        /// <returns></returns>
        public List<Order_Info> GetOrder_InfoBySpec(ISpecification<Order_Info> spec)
        {
            return _iOrderRepository.GetEntities(spec).ToList();
        }

WEB层

Web层建立一个指定的规约,并为规约组件所需要的数据即可

        public ActionResult List(int? userID)
        {
            ISpecification<Order_Info> spec = new OrderFromUserSpecification(userID ?? 0);
            var model = orderService.GetOrder_InfoBySpec(spec);
            return View(model);
        }

如果这时来了个新需要,使用用户名进行查询,你可以直接建立一个OrderFromUserNameSpecification的规约即可,而不需要修改OrderService,呵呵!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:EF架构~引入规约(Specification)模式,让程序扩展性更强,如需转载请自行联系原博主。

目录
相关文章
|
1月前
|
负载均衡 测试技术 持续交付
高效后端开发实践:构建可扩展的微服务架构
在当今快速发展的互联网时代,后端开发扮演着至关重要的角色。本文将重点探讨如何构建可扩展的微服务架构,以及在后端开发中提高效率的一些实践方法。通过合理的架构设计和技术选型,我们可以更好地应对日益复杂的业务需求,实现高效可靠的后端系统。
|
1月前
|
监控 持续交付 API
构建高效可扩展的微服务架构
在当今快速迭代和竞争激烈的软件市场中,构建一个高效、可扩展且易于维护的后端系统变得尤为重要。微服务架构作为一种流行的分布式系统设计方式,允许开发者将应用程序划分为一系列小型、自治的服务,每个服务负责执行特定的业务功能。本文将探讨如何利用现代技术栈搭建一个符合这些要求的微服务架构,并讨论其潜在的挑战与解决方案。我们将涵盖服务划分策略、容器化、服务发现、API网关、持续集成/持续部署(CI/CD)以及监控和日志管理等关键主题,以帮助读者构建出既可靠又灵活的后端系统。
|
1月前
|
监控 Kubernetes 持续交付
构建高效可扩展的微服务架构:后端开发实践指南
在数字化转型的浪潮中,企业对软件系统的要求日益提高,追求快速响应市场变化、持续交付价值成为核心竞争力。微服务架构以其灵活性、模块化和独立部署的特点,成为解决复杂系统问题的有效途径。本文将深入探讨如何构建一个高效且可扩展的微服务架构,涵盖关键设计原则、技术选型及实践案例,为后端开发者提供一条清晰的指导路线,帮助其在不断变化的技术环境中保持竞争力。
133 3
|
24天前
|
存储 缓存 监控
构建高效可扩展的后端服务架构
在当今互联网时代,构建高效可扩展的后端服务架构对于企业的业务发展至关重要。本文将探讨如何通过合理设计和优化后端服务架构,实现系统的高性能、高可用性和易扩展性,从而满足不断增长的业务需求和用户规模。
18 0
|
13天前
|
运维 监控 自动驾驶
构建可扩展的应用程序:Apollo与微服务架构的完美结合
构建可扩展的应用程序:Apollo与微服务架构的完美结合
32 10
|
14天前
|
存储 人工智能 架构师
数据库架构模式:分片
本文介绍了数据库分片的概念,以及各自的使用场景,分片可提升可扩展性、性能和高可用性。
|
18天前
|
前端开发 安全 JavaScript
计算机软件从 CS 模式到 BS 架构迁移背后的动因
计算机软件从 CS 模式到 BS 架构迁移背后的动因
23 0
|
23天前
|
负载均衡 网络协议 Java
构建高效可扩展的微服务架构:利用Spring Cloud实现服务发现与负载均衡
本文将探讨如何利用Spring Cloud技术实现微服务架构中的服务发现与负载均衡,通过注册中心来管理服务的注册与发现,并通过负载均衡策略实现请求的分发,从而构建高效可扩展的微服务系统。
|
27天前
|
存储 监控 安全
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
62 1
|
1月前
|
运维 安全 Linux
LAMP架构调优(八)——Apache Worker模式调优
LAMP架构调优(八)——Apache Worker模式调优
9 0