架构之路--实战项目记录(二) 忘记数据库 开始抽象

对我而言,认识BLL层的作用,或者领域模型驱动的含义,最大的干扰来自数据库。

我们很清楚的知道UI层的含义,也知道数据层是做什么的。但对于一个简单的(甚至是相当复杂的)系统而言,实在不知道除了对数据库进行增删改查以外,还能做些什么?发布一篇博客,不就是在数据库里插入一条记录么?点击一下推荐,不就是在数据库里做一个update么?

为了避免数据库的干扰,这里,我们设定:不使用关系数据库做存储!请大家牢记,为了更清晰,更深刻的认识到这一点,我们再次明确,我们将使用最流行的NoSQL技术。牛叉吧!兴奋吧?

打满了鸡血吧!

好的,设计的任务交给你了,小李同学。

接下来,你怎么办?哎呀,我对NoSQL还不熟呀(不熟?其实除了名字知道以外,其他什么都根本就不知道)。马上开始研究一下NoSQL,看看里面有没有什么库呀,表呀之类的,好像那里面用的是集合?

如果你这样走下去的话,就偏离了DDD的宗旨了(但也不能说你“错”了)。

我是这样做的。

问:这个系统要做什么?有哪些功能?

答:发布博客,博客可以评论。可以提问题,回答问题。当然,做这些事,都得注册登录……

好,根据以上信息,我们可以抽象出这几个对象。

这是一个良好的开端。再细致点,博客和问题,都必须有标题;而博客的评论和问题的答案,不需要标题;但不管是博客还是问题,评论还是回答,都会有一个作者,都要发布时都要记录下

发布的时间,甚至发布者的IP(基于中国人都知道的原因)。博客和问题,还要记录下浏览量……

到这里,你是不是嗅到了一种什么味道?“不管……还是……都……”,共同的东西!那么想到面向对象的三大特征,“继承”就呼之欲出了。所以我们通过抽象,得到了以下的对象。

View Code
     ///   <summary>
    
///  Article is abstract, means it's not a really entity
    
///   </summary>
     public  abstract  class Article : Entity< int>
    {
         #region Properties

         #region Content
         public  virtual  string Body {  getset; }
         #endregion

         #region Log
         ///   <summary>
        
///  Need not set manually in most scenarios
        
///   </summary>
         public  virtual  string PublishIP {  getset; }
         ///   <summary>
        
///  Need not set manually in most scenarios
        
///   </summary>
         public  virtual DateTime? LastModifiedTime {  getset; }
         #endregion

         #region Associates
         public  virtual User Author {  getset; }
         #endregion

         #endregion

         #region Public Methods

         public  virtual  void Publish()
        {
             #region set some default value

            setCreatedTime();
            setLastModifiedTime();
            setPublishIP();

             #endregion
        }

         #endregion

         #region Protect Methods

         protected  virtual  void setLastModifiedTime()
        {
             if (LastModifiedTime ==  null)
            {
                LastModifiedTime = DateTime.Now;
            }
        }

         protected  virtual  void setPublishIP()
        {
             if ( string.IsNullOrEmpty(PublishIP))
            {
                PublishIP = HttpContext.Current.Request.UserHostAddress;
            }
        }

         #endregion
    }


     ///   <summary>
    
///  represent article can be regarded as the main part of one page, e.g. Blog and Question
    
///   </summary>
     public  abstract  class MainArticle : Article
    {
         #region Properties

         #region Content
         public  virtual  string Title {  getset; }
         public  virtual  string Keywords {  getset; }
         #endregion        

         #region Credit
         public  virtual  int ViewCount {  getset; }
         #endregion

         #region Log
         #endregion

         #endregion

         #region Methods

         public  virtual  void View()
        {
            ViewCount++;
        }

         #endregion

    }

     public  class Blog : MainArticle
    {
         #region Properties

         #region Associates
         public  virtual CategoryOfBlog Category {  getset; }
         #endregion

         #region Content
         public  virtual  string BlogAbstract {  getset; }
         #endregion

         #endregion
    }


     public  class CommentOfBlog : AttachedArticle
    {
         #region Properties

         #region Associates
         public  virtual Blog ReferredBlog {  getset; }
         public  virtual CommentOfBlog ReferredComment {  getset; }       
         #endregion

         #endregion
    }

     public  abstract  class AttachedArticle : Article
    {

    }

     public  class Answer : AttachedArticle
    {
         #region Properties

         #region Associates
         public  virtual Question ReferredQuestion {  getset; }
         public  virtual Answer ReferredAnswer {  getset; }
         #endregion

         #endregion  
    }

这样做的好处,很明显的,就是减少了重复代码。“代码越少越好”,我深以为然。当然,随之而来,还有其他好处,容后再表,呵呵。这里只说一句,良好的抽象是实现设计模式的基础。

其实,只要有面向对象的思想,进行这样的抽象是相当容易的(这样的抽象也是不对的,以后再论述)。但我们常常会被关系型数据库所干扰(尤其是有一定开发经验的程序员),而不敢进行这种“大胆的”抽象。因为即使将代码写到这里了,也得面临一个很现实的问题,接下来怎么办?最终我们怎么把这些对象持久化(保存到数据库或其他媒介中去)。这就是我们接下来要进行的工作了。

最后,对那些还想着数据库的同学,再重复强调一点:这个项目,我们用NoSQL!哦,sorry,改主意了,大家反映NoSQL太难了,又说干脆用xml文件吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介:  本项目课程是一门极具综合性和完整性的大型项目课程;课程项目的业务背景源自各类互联网公司对海量用户浏览行为数据和业务数据分析的需求及企业数据管理、数据运营需求。 本课程项目涵盖数据采集与预处理、数据仓库体系建设、用户画像系统建设、数据治理(元数据管理、数据质量管理)、任务调度系统、数据服务层建设、OLAP即席分析系统建设等大量模块,力求原汁原味重现一个完备的企业级大型数据运营系统。  拒绝demo,拒绝宏观抽象,拒绝只讲不练,本课程高度揉和理论与实战,并兼顾各层次的学员,真正从0开始,循序渐进,每一个步骤每一个环节,都会带领学员从需求分析开始,到逻辑设计,最后落实到每一行代码,所有流程都采用企业级解决方案,并手把手带领学员一一实现,拒绝复制粘贴,拒绝demo化的实现。并且会穿插大量的原创图解,来帮助学员理解复杂逻辑,掌握关键流程,熟悉核心架构。   跟随项目课程,历经接近100+小时的时间,从需求分析开始,到数据埋点采集,到预处理程序代码编写,到数仓体系搭建......逐渐展开整个项目的宏大视图,构建起整个项目的摩天大厦。  由于本课程不光讲解项目的实现,还会在实现过程中反复揉和各种技术细节,各种设计思想,各种最佳实践思维,学完本项目并勤于实践的话,学员的收获将远远超越一个项目的具体实现,更能对大型数据系统开发产生深刻体悟,对很多技术的应用将感觉豁然开朗,并带来融会贯通能力的巨大飞跃。当然,最直接的收获是,学完本课程,你将很容易就拿到大数据数仓建设或用户画像建设等岗位的OFFER课程模块: 1. 数据采集:涉及到埋点日志flume采集系统,sqoop业务数据抽取系统等; 2. 数据预处理:涉及到各类字典数据构建,复杂结构数据清洗解析,数据集成,数据修正,以及多渠道数据的用户身份标识打通:ID-MAPPING等;3. 数据仓库:涉及到hive数仓基础设施搭建,数仓分层体系设计,数仓分析主题设计,多维分析实现,ETL任务脚本开发,ETL任务调度,数据生命周期管理等;4. 数据治理:涉及数据资产查询管理,数据质量监控管理,atlas元数据管理系统,atlas数据血缘管理等;5. 用户画像系统:涉及画像标签体系设计,标签体系层级关系设计,各类标签计算实现,兴趣类标签的衰减合并,模型标签的机器学习算法应用及特征提取、模型训练等;6. OLAP即席分析平台:涉及OLAP平台的整体架构设计,技术选型,底层存储实现,Presto查询引擎搭建,数据服务接口开发等;7. 数据服务:涉及数据服务的整体设计理念,架构搭建,各类数据访问需求的restapi开发等;课程所涉及的技术: 整个项目课程中,将涉及到一个大型数据系统中所用到的几乎所有主要技术,具体来说,包含但不限于如下技术组件:l Hadoopl Hivel HBasel SparkCore /SparkSQL/ Spark GRAPHX / Spark Mllibl Sqoopl Azkabanl Flumel lasal Kafkal Zookeeperl Solrl Prestop

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值