Johnny's Collections

生活总是有太多的无奈与失望,让我们以在努力学习和工作中获得的成就感和快乐来冲淡它们。

BlogJava 首页 新随笔 联系 聚合 管理
  10 Posts :: 0 Stories :: 80 Comments :: 0 Trackbacks

2010年6月26日 #

    一直对BIO、NIO、AIO不太理解,特别是阻塞与异步的区别。Google了一下,一篇文章中的4张图很形象的表述了4种IO模型的原理和区别,收藏一下。

    首先,贴一张表示四种IO模型的图:



同步阻塞IO:


同步非阻塞IO:



异步阻塞IO:


异步非阻塞IO:
posted @ 2012-05-20 00:12 Johnny.Liang 阅读(612) | 评论 (0)编辑 收藏

6月下旬,由于个人发展的原因,离开了做银行外包的F公司,也离开了S城,结束了2个半月短暂的S城之旅,重新回到了土生土长的G城,也加入了一家互联网公司,工作这么多年,都是做企业级应用,这次是我第一次从事互联网技术工作,我终于落网了。

从事互联网技术工作与企业级应用有很大的不同,考虑的东西更多了。由于缺乏互联网相关的开发经验,很多东西需要去学习,同时,加入新公司后,终于真正的当上了Leader,这次终于可以自己一手一脚的组件自己的团队了,所以,除了技术工作,还有一大堆管理工作要做。几个月来,晚上9点半过后下班,周末带电脑回家继续工作已经成为了习惯。总之,每天都有忙不完的工作,生活的70%时间都在工作上。

正因如此,本来想坚持写的博客暂停了,《领域驱动设计》的系列文章也暂停了很久。在此,向一直关注我的文章的同学说声抱歉,我可能有一段时间要暂停写博了。不过,技术依然是我的最爱,IT依然是我的事业,等我在新公司的工作上轨之后,我就会回来。各位,再会!

posted @ 2010-12-14 22:46 Johnny.Liang 阅读(623) | 评论 (3)编辑 收藏

领域驱动设计系列文章(3)——有选择性的使用领域驱动设计

 

本系列的第一篇博文抛砖引玉,大谈领域驱动设计的优势,这里笔者还是希望以客观的态度,谈谈领域驱动设计的缺点及其不适合使用的场景,以让读者可以有选择性的使用领域驱动设计。

 

       我们知道,没有最好,只有最合适,设计也是一样。因此,所谓设计,就是以你和你的团队的知识、经验和智慧,全面充分的考虑各种内外因素后,在你们的设计方案中作出合理的选择的过程。而这些影响你们选择的因素主要有:

 

  • 技术框架的特征和约束(如果你的项目决定使用C语言进行开发,那么首先在设计方法上,就需要使用面向过程而非面向对象的设计方法)。

 

  • 时间的压力和约束(你永远不可能告诉你的老板,给我10年时间,我和我的团队将为你设计出世界上最优秀的软件)。

 

  • 你的团队的能力、经验、性格、价值观等因素的约束(你不能期望一个长期从事遗留系统维护项目或大部分成员是缺乏经验的高校毕业生的团队能很好的按照你的设计意图去实现你的高度抽象的优秀设计,同时你也别指望一帮家里经济条件不错,本着过来熬时间的家伙会乐意与你一起刻苦钻研、精益求精)。

 

  • 你的系统的特征(如果你想把一个足够简单而且在可以预计的将来都不存在很大规模的需求变更的系统设计得很复杂,很精妙,具有很好的扩展性,但要为此付出巨大的时间、人力成本,这显然是一种不理智的过度设计(Over design))。

 

  • 其他外在因素的约束(你的项目需要参与投标,你必须压缩人力、时间等以让你的项目成本成为巨大的竞争资本)。

 

当然,上述的考虑因素站在比较高的角度,通常是项目经理、架构师需要考虑的问题,但这当中你应该会得到一些启发。回到我们的主题,我们首先看看,领域驱动设计相对于传统的面向过程式的设计,有什么缺点:

 

  • 复杂化:面向过程思维之所以一直很受欢迎,是因为它很直观,非常符合大部分人的思维习惯,大部分人拿到一个问题,通常都是会很直观的想第一步做什么、第二步做什么,如果怎样,应该怎样,否则怎样……,可以说,任何水平的程序员,都能很好的使用面向过程的方法进行设计和开发。同时,由于我们教育水平的落后和整体IT环境的制约,可以这样说,真正掌握面向对象思维和设计方法的程序员的比例非常低(虽然绝大部分都使用面向对象的语言和工具),而本身面向对象思维要求人有很好的抽象思维能力,因为你需要把一个复杂的系统一层层的抽象为简单的部分,需要把现实世界的事物(有些是可见的,但有些是不可见)合理的抽象为计算机世界的不同元素。这些都不是一些很容易做的事情,要做得好,就更难。


  • 团队的抗拒:如果你的团队(很大可能)大部分人都习惯于用很直观的面向过程的方式进行设计和开发,你需要推动你的团队转换思维来采用面向对象的方式进行领域驱动设计,通常会遭到多数人的抗拒。因为人都是有惰性的,他们习惯安于现状,而改变是痛苦的,他们要付出额外的努力,需要进行学习,但以笔者的经验,相当一部分程序员,特别是有一定工作年限的程序员,他们从事IT工作都只是为了获得一份不错的报酬,因此他们的学习动力非常有限,而且,他们都相当自负,被说服的难度比较大。



  • 管理、开发和维护的成本高:复杂度更高,意味着你需要花更多的时间进行设计,同时需要花出额外的时间进行必要的培训,而且需要有更完善的文档(设计文档,API文档,培训文档等)。领域驱动设计的抽象程度比较高,因此必需有良好的文档,否则,随着项目的不断迭代、升级和维护,它很容易因为后来者的误解而慢慢回归面向过程的设计,甚至会变得“四不象”,领域驱动设计的成本优势是随着时间的推移慢慢体现的(见下图),如果出现这种情况,所有前面付出的努力都会付诸东流。


系统的初始阶段,领域驱动设计需要付出更大的成本,但随着时间的推移,领域驱动设计的成本效益优势会逐步显现

  • 性能比较低:使用纯面向对象的方式进行领域驱动设计的程序,其系统开销通常要比面向过程设计的程序高,从而性能相对较低(关于具体的例子,后续的博文会提及)。

 

那么,假设我们在时间、团队能力及各种资源都允许的情况下,是否就可以麻木的全盘使用领域驱动设计呢?正如本博文的标题一样,答案是否定的,我们需要有选择性的使用。让我们来看看一些指导性原则:

 

  • 使用领域驱动设计,并不代表整个系统的方方面面都必须遵从领域驱动设计的原则,需要根据实际情况,让适合的部分使用领域驱动设计,让不适合的部分使用面向过程的设计。


  • 对于那些业务规则非常简单,通常只有增、删、改、查的简单操作,而且也不大可能发生大规模需求变更的模块,可以让业务实体成为一个“贫血模型”,例如一些基础数据:系统参数、商品类型、国家、地址信息(注:对于这点,本人持保留态度,因为这些业务虽然非常简单,但既然选择了领取驱动设计,即使把这些业务实体设计为“充血模型”,即把极其简单的业务逻辑也封装在业务实体中,也并不比使用“贫血模型”成本高,而它却带来了统一设计风格的好处)。


  • 对于查询操作,特别是复杂的查询操作,出于性能的考虑,可以用结构化查询逻辑一次性完成,并把这些逻辑封装在Repository(即技术上的DAO)中(这方面的具体例子,后面关于“查询通道”和“领域对象仓库”的博文会更具体的阐述)。我们可以看到,对于一些业务视图,以及报表模块,很明显不适合使用面向对象的方式设计,因为这些“视图”和“报表”,本质上就不是业务实体。


  • 同样出于性能的考虑,在业务实体的实现逻辑中,某些操作不适合过度偏执的使用面向对象方式。例如,在“订单”的“新增订单明细”(order.addOrderItem(orderItem))中,如果业务逻辑规定一张订单中包含优惠商品的明细数目不能超过20条,使用面向对象的方式,就需要把订单中的所有订单明细全部加载,然后逐个明细判断其对应的商品是否优惠商品,再统计出优惠商品的数目,这样很明显是低效率和高开销的,这里只需要使用Repository提供的一个统计方法,用一个结构化查询逻辑返回统计结果即可,而这就是非面向对象的方式。


本博文给有志于领域驱动设计的读者泼了一下冷水,提出一些“反模式”(Bitter),是为了让读者冷静一下,在领域驱动设计过程中作出更灵活和更合理的选择。关于这方面的论述,笔者在这里浅尝则止,限于水平、经验和表达能力,不敢胡乱卖弄,建议读者可以参考阅读Martin Fowler的《Patterns of Enterprise Application Architecture》一书的相关观点。

posted @ 2010-06-26 17:47 Johnny.Liang 阅读(3198) | 评论 (2)编辑 收藏