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

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

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

      前言

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

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

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

      《head first》中的工厂模式

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

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

  工厂模式成为解决问题的方案,经过工厂模式,适当的建立接口,将代码中的具体过程进行屏蔽,从而提升了代码的灵活性。又分为静态工厂、简单工厂模式、工厂方法模式、抽象工厂模式等多种不一样的模式。例如,咱们可能会编写一段下面的代码。   设计

 1 public abstract class FactoryPizzaStore
 2 {
 3         public Pizza OrderPizza(string type)
 4         {
 5 
 6             Pizza pizza = CreatePizza(type);
 7             return pizza;
 8         }
 9         public abstract Pizza CreatePizza(string type);
10 }

      咱们能够看到,这只是一段最普通的工厂代码,定义了一个抽象对象,若是须要实现成员,只需继承此对象,并重载方法,这种方法能够很是便捷的将内部对象的建立过程进行封装,实现了代码内聚性的显著提升。code

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

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

领域工厂模式

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

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

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

的所有规则,并经过提供相关接口、建立对象的抽象视图,让建立的过程符合规则。

  在领域工厂模式中,每每有如下要求:

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

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

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

领域仓储对象

  在软件系统研发过程当中,咱们一般须要使用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);
} 

  仓储的引入有不少优势:

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

      二、实现数据源解耦。

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

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

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

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

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

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

      结语

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

相关文章
相关标签/搜索