H5 + WebGL 展示的3D无人机
天佑武汉,天佑中国。这次为全国人民作出巨大牺牲的武汉人是坚强和担当的。
这次疫情期间的自我隔离的一个副作用是第一次享受这个超长假期,本来想好好学习一下Web技术的,但家里的唯一一台计算机被占用,不得已只能停下脚步,继续研究一下这个开源项目的领域模型。
搅拌站的生产管理事是以短期计划为核心展开的,每天生产调度人员根据工地的需求制定针对创建一个“日计划”。实验室人员会为这个日计划创建生产配方。日计划的生产不是连续性的,他会分解成很多小的批次计划。分解批次计划的原因是因为混凝土的交付有很多步骤组成,首先由搅拌站生产,再由搅拌车运输到工地,最后由混凝土泵车泵送到指定的浇筑位置。根据这个生产流程,我们很容易设计出模型的最初版本
再实际生产过程中,针对一些特殊的情况,批次计划会增加一些附加的动作,常见的有,每天第一批次是会额外生产一盘的砂浆(用于泵车输送管的润滑),如果是工地第一次开盘,还要打印质保书。这样在批次计划前应该增加一个批次计划报的对象来包含这些额外的动作。
如果仔细分析以上对象,不管是生产计划还是附加动作或者交付动作,他们都可以被执行或放弃,都需要跟踪执行的结果,本质上都是一个可以被执行的动作对象。并且可以根据动作执行的不同结果(如因为车辆问题,混凝土没有送到工地)可以启动一些补偿或后续动作。再这里我们可以引入动作模式(Martin Fowler 分析模式)。
在动作模式下,我们可以通过提议动作和执行动作更加方便的跟踪动作提议和执行的差异,比如计划给工地送8方混凝土,而因为混凝土质量问题被退货。
对于动作执行的结果是否成功,最简单的办法是使用一个标准属性。这是方式的弊端在于过于简单,以至于我们只能记录动作是否执行失败,无法记录失败的原因。比如送到工地的混凝土的某几项指标不合格而引起的工地退货。在这里比较好的方法是使用观察模式,可以观察和记录对混凝土的指标的检验记录。并且通过观察的结果来判断动作是否成功。这样可以更加灵活的提供结果的判断逻辑。
Android教程2020 – RecyclerView实际使用
在引入了动作模式后,我们就可以使用计划类型来实现对动作的编排和依赖,计划实质上是动作按顺序的聚合(Martin Fowler 分析模式)。
这里我们的日计划和批次计划就可以做为计划的子类型,只不过 需要在日计划类型里增加一个分配批次计划的方法,同时在计划的超类里面增加产量的属性。在分配批次计划的方法里一般需要制定车辆,这样就可以按照车辆的运输能力确定批次的产量。在一些特殊的情况下,也可以不指定车辆,这是预计生产的产量就按车队里所有车辆的最小运输能力设置批次方量。在一些软件中,类似的问题会被放置在词典中,这并不是个好的办法,词典中大量夹杂着领域逻辑的数据,词典本身就是一个令人费解的概念,虽然他能很简单的解决不少问题。最小运输能力应该由领域模型中的服务对象提供。但我们的系统中没有包含车辆管理的逻辑,所有车辆指派的功能准备从车辆管理服务接口获取。即使这样,我们也准备使用策略模式,支持使用内置的的车辆管理领域模型。
计划的另一个问题是资源的消耗。我们关注的资源主要有生产原料的消耗,生产混凝土的搅拌站,运输的搅拌车和泵送的混凝土泵车。其中混凝土搅拌站作为资源的占用是领域模型的另一个重点,搅拌车和泵车不作为我们的关注的核心对象,搅拌车由其他服务提供管理,泵车作为资源管理对于系统没有什么价值。这样我们就可以使用一个比较简化的资源分配模型。
在资源分配模型中,最核心的是为提议动作分配的预定的资源,而执行动作则是实际消耗的资源,这样我们就可以精确的统计实际消耗的物料,在配合生产动作和交付动作的完成情况,就可以精确的对生产完没交付成功的方量和消耗进行准确的统计。
以上描述了混凝土搅拌站生产计划模型的初步演进过程,其中大量借鉴了Martin Fowler 分析模式。当然这知识初步的模型,还有很多不合理的地方等着我们去重构。
在使用领域模型后,每次流程处理和执行会设计到大量的领域对象,这样会对UI层的调用产生巨大的困难,并且当UI层设计到大量的领域对象时,必然会带来领域知识的泄露,为此,我们会在增加一个应用层,来封装对领域模型的调用同时提供简单的接口。现在软件的人际交互的要求越来越高,在这方面,可以通过可页面紧密相关的门面对象(Facade)实现。使用领域模型对数据的存储也是个巨大的挑战,幸好现在有很多成熟的解决方案甚至技术框架能帮我们实现对象到数据库的映射。
你要问我应用层?我就和你扯扯扯