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

简介: 对我而言,认识BLL层的作用,或者领域模型驱动的含义,最大的干扰来自数据库。我们很清楚的知道UI层的含义,也知道数据层是做什么的。但对于一个简单的(甚至是相当复杂的)系统而言,实在不知道除了对数据库进行增删改查以外,还能做些什么?发布一篇博客,不就是在数据库里插入一条记录么?点击一下推荐,不就是在数据库里做一个update么?为了避免数据库的干扰,这里,我们设定:不使用关系数据库做存储!请大家牢记,为了更清晰,更深刻的认识到这一点,我们再次明确,我们将使用最流行的NoSQL技术。
对我而言,认识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文件吧。

相关文章
|
2月前
|
前端开发 JavaScript 测试技术
Kotlin教程笔记 - 适合构建中大型项目的架构模式全面对比
Kotlin教程笔记 - 适合构建中大型项目的架构模式全面对比
38 3
|
2月前
|
监控 前端开发 数据可视化
3D架构图软件 iCraft Editor 正式发布 @icraft/player-react 前端组件, 轻松嵌入3D架构图到您的项目,实现数字孪生
@icraft/player-react 是 iCraft Editor 推出的 React 组件库,旨在简化3D数字孪生场景的前端集成。它支持零配置快速接入、自定义插件、丰富的事件和方法、动画控制及实时数据接入,帮助开发者轻松实现3D场景与React项目的无缝融合。
196 8
3D架构图软件 iCraft Editor 正式发布 @icraft/player-react 前端组件, 轻松嵌入3D架构图到您的项目,实现数字孪生
|
2月前
|
存储 SQL Apache
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
Apache Doris 是一个基于 MPP 架构的高性能实时分析数据库,以其极高的速度和易用性著称。它支持高并发点查询和复杂分析场景,适用于报表分析、即席查询、数据仓库和数据湖查询加速等。最新发布的 2.0.2 版本在性能、稳定性和多租户支持方面有显著提升。社区活跃,已广泛应用于电商、广告、用户行为分析等领域。
Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
|
2月前
|
缓存 关系型数据库 MySQL
高并发架构系列:数据库主从同步的 3 种方案
本文详解高并发场景下数据库主从同步的三种解决方案:数据主从同步、数据库半同步复制、数据库中间件同步和缓存记录写key同步,旨在帮助解决数据一致性问题。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
高并发架构系列:数据库主从同步的 3 种方案
|
2月前
|
SQL 关系型数据库 数据库
国产数据实战之docker部署MyWebSQL数据库管理工具
【10月更文挑战第23天】国产数据实战之docker部署MyWebSQL数据库管理工具
178 4
国产数据实战之docker部署MyWebSQL数据库管理工具
|
2月前
|
存储 NoSQL 分布式数据库
微服务架构下的数据库设计与优化策略####
本文深入探讨了在微服务架构下,如何进行高效的数据库设计与优化,以确保系统的可扩展性、低延迟与高并发处理能力。不同于传统单一数据库模式,微服务架构要求更细粒度的服务划分,这对数据库设计提出了新的挑战。本文将从数据库分片、复制、事务管理及性能调优等方面阐述最佳实践,旨在为开发者提供一套系统性的解决方案框架。 ####
|
2月前
|
存储 SQL 数据库
深入浅出后端开发之数据库优化实战
【10月更文挑战第35天】在软件开发的世界里,数据库性能直接关系到应用的响应速度和用户体验。本文将带你了解如何通过合理的索引设计、查询优化以及恰当的数据存储策略来提升数据库性能。我们将一起探索这些技巧背后的原理,并通过实际案例感受优化带来的显著效果。
58 4
|
2月前
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
在 Android 开发中,选择合适的架构模式对于构建中大型项目至关重要。常见的架构模式有 MVVM、MVP、MVI、Clean Architecture 和 Flux/Redux。每种模式都有其优缺点和适用场景,例如 MVVM 适用于复杂 UI 状态和频繁更新,而 Clean Architecture 适合大型项目和多平台开发。选择合适的架构应考虑项目需求、团队熟悉度和可维护性。
64 6
|
2月前
|
存储 前端开发 数据可视化
在实际项目中,如何选择使用 Flux 架构或传统的 MVC 架构
在实际项目中选择使用Flux架构或传统MVC架构时,需考虑项目复杂度、团队熟悉度和性能需求。Flux适合大型、高并发应用,MVC则适用于中小型、逻辑简单的项目。
|
2月前
|
消息中间件 数据库 云计算
微服务架构下的数据库事务管理策略####
在微服务架构中,传统的单体应用被拆分为多个独立的服务单元,每个服务维护自己的数据库实例。这种设计提高了系统的可扩展性和灵活性,但同时也带来了分布式环境下事务管理的复杂性。本文探讨了微服务架构下数据库事务的挑战,并深入分析了几种主流的事务管理策略,包括Saga模式、两阶段提交(2PC)以及基于消息的最终一致性方案,旨在为开发者提供一套适应不同业务场景的事务处理框架。 ####