首页 编程语言 领域驱动设计,让程序员心中有码(七)

领域驱动设计,让程序员心中有码(七)

-设计原则和设计模式,互联网开发者们共同的追求

      前言

  多年来,笔者一直从事传统软件企业的软件开发和项目管理工作。笔者发现在众多的传统软件企业中,评判优秀开发者的标准往往是技能的熟练程度,基本上都是以梭代码的速度论英雄。有人评价说,这种开发可以称之为cv编程,即ctrl+c和ctrl+v编程为主。这种开发往往对开发者的技能要求并没有想象中的那么高,由于工时和合同的限制,不得不压缩开发时间,通过靠密集的劳动力资源、较高的工作强度来完成项目的开发。这种模式,通过简单的复用历史代码,可以更快的输出结果,对于中小型企业和一些外包企业来说,也意味着更快的项目完成速度、而越快做完项目,也意味着可以越快收回合同款,尽快开始下一个项目。

  然而,也必须承认,在这种模式下,代码的质量取决于项目管理者对于技术和代码的把握能力,如果摊上不懂技术的项目管理者以及对于代码质量没有要求的研发人员,可能最终输出的代码,将成为一团乱麻,只能在一个个项目中无穷次的积累,直到遇到一群优秀的开发人员费劲心力把体系重构为止。

  而当今互联网时代下,面向互联网的应用开发,不再追求短期成效,更在乎长期技术的沉淀,这个过程中,也对开发者提出了更高的要求。互联网行业的开发者,不仅仅要求代码梭得快,还在乎编写代码编写的质量,谁能编写出更加优美的代码,往往也更容易受人欢迎。于是,作为优美代码代名词的SOLID设计原则和很多种设计模式实际上成为了非常基础的一种能力,甚至于许多资深的开发者,经常会乐此不疲的进行各种代码的重构,也是期待能够更好的将设计模式揉碎了,应用到代码中,更好的实现高内聚、低耦合的目标。

      《head first》中的工厂模式

   在著名小红书《Head First》一书中,描述了多种设计模式,这些由资深IT技术大牛们抽象化出来的最佳代码实践,初读起来也许简单明了,但是细细品味起来,却意味深长。

   在传统软件开发实践工程中,往往会下意识的使用New关键字产生对象实例。通过这种方式进行代码的编写,固然会带来代码上的开发速度,但是同样也会给对象的生成带来一些问题。例如,对象的构造,往往附带了许多复杂的条件:如需要进行一些初始值的设置,如需要初始化与之相关的子类,或者需要预先执行许多初始化方法,那么就可能意味着代码的构造中会产生一系列复杂、与主流程无关的代码。如何让轻松方便的构造代码、而不去关心具体的实现细节呢?

  工厂模式成为解决问题的方案,通过工厂模式,适当的创建接口,将代码中的具体过程进行屏蔽,从而提高了代码的灵活性。又分为静态工厂、简单工厂模式、工厂方法模式、抽象工厂模式等多种不同的模式。

      我们可以看到,这只是一段最普通的工厂代码,定义了一个抽象对象,如果需要实现成员,只需继承此对象,并重载方法,这种方法可以非常便捷的将内部对象的创建过程进行封装,实现了代码内聚性的显著提高。

领域驱动中的工厂模式和仓储模式

         在领域驱动中,将工厂模式引入其中,让其产生了不同的含义。在上一章,我们了解到,随着软件系统复杂性的显著提高,维护模型实例的生命周期变成了一件非常困难的事情,因此通过引入一个聚合Aggregate对象,可以有效的将复杂的模型复杂的生命周期的各个阶段进行封装,通过一系列固定的规则,实现了对数据更加的控制。而这种控制,则是通过工厂模式和仓储模式来实现的。这两种模式,实现了对Aggregate对象的操作,实现了复杂的生命周期转换复杂性的良好封装。

领域工厂模式

  一个复杂的软件系统,往往如同生产一台汽车,它由许多个不同的部件组成,每个部件间通过一系列复杂的协同运动来实现整体的职能。对于用户而言,汽车是如何装配的,并不是他所关心的问题,他只在乎如何驾驶这辆汽车。这意味着,装配过程,应该与对象要执行的工作分开。软件系统同样如此,我们设计了一个复杂的聚合对象,这个对象内部有大量的实体或者值对象。如果开发者需要使用这个对象,必须按照一系列规则来进行操作。

在这个聚合对象的生命周期中,如果将创建的过程按照调用的场景,分拆到不同的环节中,可能使代码的耦合性急剧提高,带来的将是后期高昂的更改成本。

  在领域驱动设计中,复杂对象的创建过程往往是领域层的核心职能,但是,对于这个复杂对象创建过程,又显然不能有简单的Service对象来实现,因此,需要引入工厂模式。封装创建复杂对象或聚合对象

的全部规则,并通过提供相关接口、创建对象的抽象视图,让创建的过程符合规则。

  在领域工厂模式中,往往有以下要求:

    1、创建过程的原子性、满足创建所需的所有规则。由于我们引入工厂的目的,是为了将复杂的常见过程进行封装,因此我们应当确保创建过程要产生一致状态的对象。例如创建实体,应当满足聚合的全部规则、创建值对象,应该被设置为默认的参数,如果无法创建参数,应该抛出异常,或者提供处理机制,确保不会影响代码的执行。

    2、工厂模式是一种抽象对象,而不是具体对象。意味着这个过程,不会产生具体对象,也就避免了与下层对象间不必要的耦合。

    工厂模式不仅仅可以应用于对象生命周期的开始阶段,也可以在对象的重建过程中发挥作用,例如在使用关系型数据库和非关系数据库组成的复杂体系中,通过对象映射技术,可以实现对现有数据的装载。

领域仓储对象

  在软件系统研发过程中,我们通常需要使用SQL语句,直接调用基础设施层中的某个方法,实现了一系列数据转换。有时候,我们会引入AutoMap组件,实现从实体层到模型层对象的封装,这种模式广泛存在于我们的开发过程中,但是如果直接访问基础设施层,则可能增加对于数据库不必要的操作,并导致模型的价值可有可无。而且随着开发过程的推进,有可能会倾向于直接使用多次遍历的方式,提取具体对象,而忽略了Aggregate,并使得实体层成为单纯的数据容器。

  因此,通过引入仓储模式,可以为我们的实现过程提供便利。通过仓储模式,封装一系列数据库操作的方法,让我们的注意力更关注于模型中。客户端通过查询方法,向仓储中请求对象,然后再返回用户所需的对象。

  这段代码大概是这样的:

public interface IRepository<T> where T : EntityBase
{
    T GetById(int id);
    IEnumerable<T> List();
   IEnumerable<T> List(Expression<Func<T, bool>> predicate);    

   void Add(T entity);    

   void Delete(T entity);    

   void Edit(T entity);

}

  仓储的引入有很多优点:

      1、为访问者提供简单的模型,可用来获取持久化对象并管理他们的生命周期。

      2、实现数据源解耦。

      3、实现了对象访问策略的分离。

      4、便捷的访问内存对象,减少对数据库的吞吐压力。

  在仓储的设计过程中,应当注意一下事项:

      1、对类型进行抽象。仓储的目的是为了传递具有特定类型的实例,但并非每个对象都有一个仓储来与之对应。

      2、充分解耦。仓储聚合不同的查询方法,例如将关系数据库和缓存数据库的查询方法进行封装,使得代码的过程变得易于操纵。

   3、事务可控。提供事务操作的方式,便于用户自行实现事务的管理。

      结语

    在领域驱动设计中,通过在领域层中灵活的应用仓储模式和工厂模式,实现对象的创建过程和传递过程的不同阶段,可以让代码的执行过程更加的简洁、关系更加的清晰,这也将客观上有利于我们编写出更加优秀的代码。


站心网

-设计原则和设计模式,互联网开发者们共同的追求 前言 多年来,笔者一直从事传统软件企业的软件开发和项目..

为您推荐

程序员职业发展与技能要求

程序员是从事计算机程序开发、维护和优化的专业人员。他们通过编写代码,设计软件系统,解决技术问题,推动技术创新。以下是程序员的一些关键信息:核心技能编程语言:掌握如Python、Java、C++、JavaScript等语言。..

程序员离职时删除代码注释算违法吗?

程序员离职前删除代码注释是否违法,取决于多个因素,包括雇佣合同、公司规定、法律条款以及删除行为的动机。以下是几个关键分析点:1. 合同与公司规定劳动合同或保密协议:如果合同或公司规定明确要求代码的完整性..

创造型职业程序员的无奈

编程是为数不多的一种既能满足个人爱好,又能赚钱的职业之一。烹饪是另一个这样的例子。在一般情况下,大多数职业要么不可能让你待在家里(例如医生和电工),要么你没有兴趣在家里做(例如清洁)。同样的,大多数好..

程序员副业探索之电商

目录一、小程序化妆品1.1 小程序准备(营业执照&微信支付&小程序appId)1.2 小程序开发二、拼多多电商三、跨境电商四、总结在腾讯广告工作期间,我主要负责小程序电商与广告业务,见证了互联网电商行业的剧变,特别..

谈程序员如何做好业务

前言技术能做两种事情,通过技术实现业务和通过技术支持技术。我们大部分时候做的是前者,养活我们的大部分也是业务。 近两个月,作为项目负责人角色从0到1经历了新项目的几个版本迭代,跨入了部分新领域,也有一定..

程序员增加收入的几种方法

在这个互联网飞速发展的社会,学会如何make money很重要。咱们是个俗人,赚钱才是社会生存的头等大事。这不是高山流水的世界,而是能力创造财富,对于程序员来说,更是如此。作为程序员,我们有更多挣钱的姿势,注意..

程序员跳槽到对手公司,被前老板设计陷害

这件事发生在2007年,我就职的第一家公司。今天把它整理写出来,希望它对程序员有一个警醒的作用。永远要记住,程序员的世界除了有代码,还有被套路。资深工程师的苦恼第一天到公司,是浩子带着我办理了入职手续。浩..

程序员如何提一个好问题

提出好的问题是在编写软件时的一个非常重要的技能。这么多年来我对此也算略有小成。这里有一些我用着觉得很棒的指导方针!开始我实际上是那种总是会问出愚蠢问题或“不好”问题的大信徒。我一直在问人们一些愚蠢并且..

我是李玉宝,我是个程序员!

听说今天我的名字很火,那我也来凑个热闹。在2015年的时候,我做过一次人生总结,当时写了:为了理想,我放弃了一切! 转眼到了2019年,说说最近一年多的一些事情吧!做的好的!坚持把权限管理框架OpenAuth.Net做了..

程序员失业日记1:工作五年,交接半天

最近发现越来越多的小伙伴被公司裁员,有的是因为公司业绩不景气被裁员,有的是因为压力太大离职。很多公司都在裁人、减员。找工作也比之前难。刚好去年我也被上家裁员了,正好做一个系列的日志,希望能帮到在找工作..

改善程序员生活质量的 3+10 习惯

一封离职邮件2017年的一天,代码伴随着手指极具节奏感地输出在IDE上,突然某Chrome插件弹出一封邮件提示:“今天是我在ThoughtWorks的最后一天”。遇到这种离职邮件,我都会点进去,一来看看是否是自己曾经共事的小..

倾听程序员的心声真的很重要

说到开发产品,没有人比程序员更了解产品。程序员知道产品的优点、缺陷、用途和潜在用途。说起这些,程序员了如指掌,如数家珍。在这个似乎无所不在的数字时代,倾听程序员必须要说的内容非常重要,而且也许比以往任..

助力程序员成功的几个好习惯

老实说,如果你google搜索“程序员的好习惯”这方面的内容,那么就会有很多大同小异的文章映入你的眼帘。但是今天我想从一个略有不同的角度来探讨这个主题。不是关于如何更擅长编程,而是如何使程序员更有市场竞争力..

倔强的程序员

对于程序员来说,大多数人公司都有技术和管理两条发展路线,通常在同一家公司,管理路线的发展可能性,要相对广阔一些;但是技术路线也有技术路线的好处,比如相对而言更依赖于硬实力,因而工作机会丰富。我相信有不..

程序员如何在当今就业市场中让自己脱颖而出

俗话说,钱不是万能的,但没有钱是万万不能的。可见钱对于生活的重要性。不管你从事什么职业,实现财务自由才能让你无所畏惧地应对挑战。但是还有一点是值得开发人员所关注的:如何脱颖而出与众不同。毫无疑问,软件..

如何成为一名成功的程序员

编程是一个仅靠兴趣仍不足以抵达成功彼岸的领域。你必须充满激情,并且持之以恒地不断汲取更多有关编程的知识。只是对编程感兴趣还不足以功成名就——众所周知,我们工作起来像疯子。编程是一个没有极限的职业,所以..

写作路上的这些小成绩,铸就了一个不平庸的程序员

01 好的写作平台可以加速我们的成长“路漫漫其修远兮,吾将上下而求索”,在写作这条漫漫长路上,我已经求索了将近5年的时间;在这5年时间里,有过兴奋,有过迷茫,但幸好,我未曾放弃。2014年的4月初,我在ITeye(..

程序员如何讲清楚技术方案

最近在评审技术方案,和代码review的时候,遇到刚入行的同学们,很多都讲不清楚技术方案。具体表现是:上来不说需求,直接说算法实现。台下一头雾水,根本不知道设计方案是否合理。描述完需求后,又直接看代码,看表..

排除万难,我终于入了程序员的坑

“恭喜你,成功的避过了所有的正确答案,选择了错误答案”。没错,我是一个数学专业的普通大学生,排除万难,我终于还是入了程序员的坑。1. 生活爆锤了我一顿我是一个平凡的人,人生也一直都是平淡且稀里糊涂的!像..

如何处理前任程序员留下的代码

作为软件工程师不可避免会遇到的一个场景是:我们在改变或添加一个功能到不是我们创建的、我们不熟悉的、与我们负责的系统部分无关的代码中时,会遇到麻烦。虽然这可能会是一个繁琐而艰巨的任务,但是由于使用其他开..

发表回复

返回顶部