业务逻辑(BLL)层的组织,长期以来一直是个困惑。打从开始引入ORM后,BLL层不再出现SQL语句和存储过程,感觉思路清晰了不少,现在自己对BLL结构认识大致上定型,一般根据不同方面的业务逻辑,对应不同的命名空间,亦即不同的文件夹,每个文件夹下可能有多个Helper类。对于缓存、日志、邮件等通Helper类,放在Common目录下。

  这是传统的三层架构,如果使用SOA的话,可能多一个服务层,一般来说,项目分层不要超过四层。

  下面说说创建Helper基类的目的,因为各个Helper类,尤其是在Web开发中,都面临一些类似的问题:

  1、如何和数据打交道。有了ORM不能替代我们对性能的思考,比如有时候执行完一个方法,就向数据源提交更改,有时候需要和其它方法一起执行完后再提交更改,并且共享一个数据访问连接。

  2、如何和HttpContext打交道。显然,到处写HttpContext.Current大大增加了系统的耦合性,如果将HttpContext完全排斥在业务逻辑层外,又会UI层和BLL层代码变得复杂。所以封装HttpContext的操作是必要的,同时也对单元测试性提供方便。

  3、如何处理异常和错误。有些异常不影响程序正常处理,如提醒邮件发送失败,要捕获它们,写入系统日志,或给予用户提示。令请求无法正常执行的异常则无需捕获,如数据库连接出错。不同业务逻辑处理,可能会设置一些前提条件,如果因不满足某个条件导致执行失败,也应该有相应的提示。在返回值中表示不同的提示类型,并不足以表示一些复杂多变的场景,比如批量转账,我们应将所有未成功的转账信息集中返回给前端页面。

  所以,个人认为一般的业务处理方法,只需返回成功与否即可,或是void。而将执行中的异常、消息、警告,都在Helper基类的属性中交待。

  一个基本的Helper基类,代码如下:

    /// <summary>
    /// 所有Helper的基类
    /// </summary>
    class BaseHelper<T>
    {
        private HttpContext context;
        /// <summary>
        /// Web请求上下文
        /// </summary>
        public HttpContext Context
        {
            get
            {
                if (context == null) context = HttpContext.Current;
                return context;
            }
            set { context = value; }
        }

        List<T> details;
        /// <summary>
        /// 处理细节
        /// </summary>
        protected List<T> Details
        {
            get
            {
                if (details == null) details = new List<T>();
                return details;
            }
        }

        DBEntities db;
        /// <summary>
        /// 涉及数据操作
        /// </summary>
        protected DBEntities DB
        {
            get
            {
                if (db == null) db = new DBEntities();
                return db;
            }
        }

        /// <summary>
        /// 是否在方法内保存
        /// </summary>
        protected bool AutoSave { get; set; }

        /// <summary>
        /// 保存到数据源
        /// </summary>
        protected int Save()
        {
            if (AutoSave) return DB.SaveChanges();
            else return 0;
        }
    }

另外,还有一些通用的课题,比如缓存同步、权限控制等,也感到了不少局限性,留待以后进一步解决吧。这是最后一个传统的WebForm项目,以后开发方向就以MVC为主了。

posted on 2011-02-19 20:57  小城故事  阅读(1322)  评论(0编辑  收藏  举报