模型种类繁多,目的各有不同,即使是那些金用于软件开发项目的模型也是如此。领域驱动设计要求模型不仅能够指导早期的分析工作,还应该成为设计的基础。这总设计方法对于代码的编写有着重要的暗示作用。比太明显的一点就是:领域驱动设计要求一种不同的建模方法......
模式:MDD(Model-Driven Design)
那些压根没有领域模型的项目,仅仅通过编写代码来实现一个有一个功能,他们无法利用知识消化和沟通所带来的好处如果涉及复杂的领域就会使项目举步维艰。
另一方面,许多复杂的项目确实在尝试使用一些领域模型,但是并没有把代码的编写与模型紧密联系起来。这些项目所设计的模型,在项目初期还可能用来作一些探索工作,但是随着项目的进展,这些模型与项目渐行渐远,甚至还会起到误导作用。所有模型上话费的精力都无法保证程序设计设计的正确性,因为模型和设计是不同的。
模型和程序设计的凉席可能在很多情况写被破坏,但是二者的这种分离往往是有意而为之的。很多设计方法都提倡使用完全脱离与程序设计的分析模型,并且通常祥和而这时有不同的人员开发的。之所以称其为分析模型,是因为它是对业务领域进行分析的结果,他在组织业务领域中的概念时,完全不去考虑自己在软件系统中将会起到的作用。分析模型仅仅是理解工具,人们认为把它与程序实现联系在一起无异于搅浑一池清水。随后的程序设计与分析模型之间可能仅仅保持一种松散的对应关系。再常见分析模型时并没有考虑程序设计的问题,因此分析模型很有可能无法满足程序设计的需求。
如果整个程序设计或者其核心部分没有与领域模型相对于,那么这个模型就是没有价值的,软件的正确定也值得怀疑。同时,模型和设计功能之间太过复杂的对应关系也是难于理解的,在实际项目中改变设计时也无法维护这种关系。分析和设计工作全无关联,导致在这两个过程中所获得的知识无法彼此共享。
MDD模型驱动设计不再将分析模型和程序设计分离开,而是寻求一种能够满足这两方面需求的单一模型。不考虑纯粹的技术问题,程序设计中的每个对象都反映了模型中相应概念。这就要求我们以更高的标准来选择模型,因为他必须同时是想两种完全不同的目标。
很多方法可以対领域进行抽象,也有很多种设计可以解决应用程序的问题。因此绑定模型和程序设计是切实可行的。但是这种绑定不能够因为技术考虑而削弱分析的功能,我们也不能接受那些只反映了领域概念却舍弃了软件设计原则的拙劣设计。将领域模型和程序设计紧密联系在一起是绝对是必要的,这也使得在众多可选模型中选择最实用的模型时,又多了一条选择标准。
因此:
软件系统各个部分的设计应该忠实的反应领域模型,以便体现出这二者之间的明确对应关系。我们应该反复检查并修改模型,在软件中更加自然的实现模型,及时向然他反映出更深层次的领域概念也应如此。我们需要的模型不但应该满足这两种需求,还应该能够支持健壮的Ubiquitous Language。
从模型中获取用于程序设计和基本任务分配的术语。程序代码就是模型的表达,修改代码可能就是改变模型。而模型的改变势必会影响到接下来的相应的项目活动。
完全依赖模型的实现通常需要支持建模范式的软件开发工具和语言,比如面向对象的编程。
建模范式和工具支持
为了使MDD发挥作用,一定要在可控范围内严格保证模型与设计之间的一致性,必须要运用有软件工具支持的建模范式,他可以直接模拟模型中的概念。
面向对象编程之所以功能强大,是因为它基于建模范式,并且为模型构造提供了实现方式。从程序员的角度来看,对象那个真实存在内存中,他们与其他对象相互联系,他们被组织成类,并且通过消息传递来完成相应的行为。
面向对象设计是目前大多属大象项目所使用的建模范式。
实例:从过程设计到Model-Driven Design
我们可以把PCB看做是连接各种电路元件引脚的电导体(net)的集合。电路板上通常会有成千上万个net。有一种叫做PCB布局工具的专用软件,能够为所有net安排物理布局,而不会使他们相互交叉或干扰。它的实现方法就是根据设计者规定的大量限制条件来限制布局方式以及优化路径选择。尽管PCB布局已经非常先进了,但是他仍然有一些缺陷。
其中一个问题就是这些数以千计的net都各自拥有一套布局规则,PCB工程师认为根据net自身的性质可以将其分组,同组的net应该公用相同的规则。比如,有些net构成了总线。
工程师每次用8个、16个或者256个net组合成总线,这样布局工作就更易于管理了,不但提高了效率也减少了错误。问题是布局工具中没有类似于总线这样的概念。布局规则不得不应用于成千上万个net,每次处理一个net。
机械设计:
在布局工具的这种限制下,无计可施的工程师只能编写脚本来分析布局工具的数据文件,然后将规则直接插入到文件中,最后再把他们应用与整个总线。
布局工具在net列表文件中存储每一个电路连线,如下:
Net Name Component.Pin
------------ -------------------
Xyz0 A.0, B.0
Xyz1 A.1, B.1
Xyz2 A.2, B.2
......
而布线规则被存储在类似于下面格式的文件中:
Net Name Rule Type Parameters
----------- ------------ ---------------
Xyz1 min_linewidth 5
Xyz1 max_delay 15
Xyz2 min_lineWidth 5
Xyz2 max_delay 15
......
工程师为net指定严格的命名约定,这样将数据文件的内容按照字母排序,就可以使构成同一条总线的所有net都排列在一起。然后他们编写的脚本就可以解析该文件并且基于总线来修改每个net。用来解析、处理和写入文件的实际代码太过冗长晦涩,对解释这个例子没有什么帮助,下面只列出这个处理过程的重要步骤。
1.按照net名称将net列表文件排序;
2.逐行读取文件,寻找以总线名称开头的第一行数据;
3.解析名称匹配的每一行,获取每行中的net的名称;
4.将net名称和规则文本附加到规则文件的末尾;
5.从第3步起重复执行,知道没有匹配该总线名称的行。
总线规则的输入文件采用如下的格式:
Bus Name Rule Type Parameters
------------- ------------ ---------------
Xyz max_vias 3
经过处理后,输出的是添加了net规则的文件,如下所示:
Net Name Rule Type Parameters
------------ ------------- ---------------
. . . . . .
Xyz0 max_vias 3
Xyz1 max_vias 3
Xyz2 max_vias 3
. . . . . .
我猜想第一个编写这个脚本的人只有这种简单的需求,如果情况确实如此,那么使用这样的脚本是完全合理的。
脚本的编写者试图在布局工具中的领域模型中补充“总线”这个概念,他们的脚本通过排序和字符串匹配来判断总线的存在,却没有明确的定义总线概念。
Model-Driven Design
前面我们已经描述了领域专家思考问题时所使用的概念。现在需要一些概念组织成模型,作为软件开发的基础。
用面向对象语言实现上图的这些对象后,核心功能的实现会变得的轻而易举。
方法assignRule()可以再抽象类AbstractNet中实现。而类Net中的方法assignedRules()则分配了自身的规则以及类Bus的规则。
abstract class AbstractNet {
private Set rules;
void assignRule(LayoutRule rule) {
rules.add(rule);
}
Set assignedRules() {
return ruels;
}
}
class net extends AbstraceNet {
private Bus bus;
Set assignedRules() {
Set result = new HashSet();
result.addAll(super.assignedRules());
result.addAll(bus.assignedRules());
return result;
}
}
当然,程序还需要大量的支持代码,但上面的代码片段已经实现了脚本的基本功能。这个程序还需要输入、输出逻辑,我们可以将其概括为一些简单的服务。
服务 |
职责 |
Net List import |
读取Net列表文件,为每一行数据创建Net实例 |
Net Rule exoprt |
已知Net集合,将所有附加规则写入规则文件 |
我们还需要几个工具类
类 |
职责 |
Net Repository |
提供通过名称访问Net的接口 |
Inferred Bus Factory |
已知Net集合,利用命名约定来推断总线,并且创建总线实例 |
Bus Repository |
提供功过名称访问Bus(总线)的接口 |
现在,启动应用程序,用输入数据来初始化Net和Bus仓库。
Collection nets = NetListImportService.read(aFile);
NetRepository.addAll(nets);
Collection busses = InferredBusFactory.groupIntoBusses(nets);
BusRepository.addAll(busses);
上面提到的服务和仓库都可以进行单元测试。更重要的是还可以测试核心领域逻辑。
Model-Driven Design 易于扩展,能够为规则的组合设置限制条件,还能提供一些其他的一些增强功能。
Model-Driven Design 也为测试提供了方便。它的组件都具有定义完善的接口,可以进行单元测试。而测试脚本程序的唯一方法就是将输入、输出文件进行端到端比较。
记住这样的设计不是一撮而就的。我们需要反复研究领域知识,不断重构模型,才能将领域中重要的该概念提炼成简单而清晰的模型。
- 大小: 9.8 KB
分享到:
相关推荐
这些绑定模型可以广泛应用于游戏开发中的NPC(非玩家角色)设计,电影和电视动画的制作,甚至于虚拟现实(VR)和增强现实(AR)项目。它们可以减少艺术家在骨骼设置和测试上花费的时间,使他们能够更专注于动画的...
标题中的“KinectV2结合Unity3D人物模型绑定”是指使用微软的Kinect V2传感器与Unity3D游戏引擎相结合,实现对人体动作的捕捉,并将这些动作实时地同步到Unity3D中的3D人物模型上,从而创建出互动性强、真实感高的...
在描述中提到的博文链接可能详细解析了模型绑定的实现和使用技巧,但由于无法直接访问,这里我们根据通用知识进行讲解。 模型绑定的过程通常包括以下步骤: 1. **参数匹配**:当用户提交表单或发送Ajax请求时,...
通过上述内容可以看出,在 Rails 中实现多模型绑定不仅可以简化代码编写工作,而且还能提高应用的可维护性和扩展性。掌握了这一技巧后,开发者可以更加灵活地构建复杂的业务逻辑,同时也能够充分利用 Rails 提供的...
【JBPM绑定自定义用户模型实现授权】 JBPM(Java Business Process Management)是一个开源的工作流管理系统,用于构建和管理业务流程。在JBPM中,任务的授权和分配通常基于预定义的角色-用户模型,但这种模型可能...
这些3D模型和动作绑定可以供游戏开发者、艺术家或爱好者学习、研究和参考,了解游戏模型的设计和实现过程。同时,它们也可以用于非商业项目,如粉丝创作、教学示例或个人作品集的构建。不过,值得注意的是,任何商业...
绑定是将3D模型的几何形状与骨骼系统关联的过程,使得通过操纵骨骼,模型的形状和动作能够随之变化,从而实现角色的动态效果。3DS MAX 9的绑定工具提供了强大的骨骼系统和蒙皮权重编辑功能,使得艺术家可以精确控制...
3. **动作模型**:这里的“女牧师动作模型”意味着该模型不仅有静态姿势,还包含了一系列预设的动作,如走路、跑步、施法、祈祷等,这些都是通过调整骨骼的位置和旋转来实现的。 4. **游戏开发**:在游戏开发中,...
本主题主要探讨的是如何利用.NET的数据绑定模型来创建可绑定的数据网格,以实现高效、动态的数据展示和管理。 首先,我们要理解数据绑定模型的基本概念。在.NET中,数据绑定是通过将控件(如GridView或ListView)的...
数据双向绑定的核心思想是建立模型和视图间的连接,通常通过监听和触发事件来实现。当模型数据发生变化时,通知视图进行更新;反之,当用户在视图中操作导致数据变化时,也会同步到模型。这种机制减少了开发者手动...
总结,依赖属性是WPF中的核心特性,通过它实现了控件属性与数据源的高效绑定,极大地增强了WPF应用的可交互性和灵活性。正确理解和使用依赖属性,能让你的WPF应用具备更强大的功能和更丰富的用户体验。在实际开发中...
在提供的`myMvvm-master`压缩包文件中,很可能是包含了Vue的一个简单实现或示例项目,你可以通过查看源代码进一步学习和理解Vue的双向绑定机制。通常,这样的项目会包含`main.js`入口文件、`App.vue`主组件以及其他...
总之,这个"猎天使魔女2贞德模型 Maya+obj格式 含材质带绑定"的资源为3D艺术家和游戏开发者提供了高质量的素材,他们可以通过Maya或obj格式导入模型,直接使用预设的材质和骨骼绑定进行进一步的创作,无论是用于游戏...
骨骼绑定,或称为骨架绑定,是将3D模型与骨骼结构关联的过程,使得模型的各个部分可以通过移动骨骼来实现动态效果,如走路、跳跃等。这在动画制作中至关重要。骨骼绑定涉及到权重分配,每个模型顶点都会被分配一个或...
在3D模型文件方面,woman_mainbody3 - 副本.max是3ds Max格式的模型文件,包含了模型的几何结构、骨骼绑定和动画数据。这个文件至关重要,因为它是整个3D角色的核心,包含着模型的所有形体信息和与之相关的动态属性...
在Windows Presentation ...总结来说,WPF的MVVM模式结合了数据绑定、命令绑定和事件绑定,实现了UI与业务逻辑的解耦,提供了高效且可维护的开发方式。理解并掌握这些技术对于任何WPF开发者来说都是至关重要的。
- ViewModel:作为视图和模型之间的桥梁,提供数据处理和业务逻辑,并暴露给视图的数据属性(通常用INotifyPropertyChanged接口实现属性更改通知)。 - View:WPF的XAML界面,绑定到ViewModel的属性。 2. ...
3. **ViewModel(视图模型)**:作为视图和模型之间的桥梁,ViewModel提供了用于操纵模型的公共属性和方法,并且这些属性和方法与视图中的控件进行绑定。ViewModel通过监听模型的变化并更新视图,同时响应视图的事件...
当一个数据模型的某个属性发生变化时,BaseObservable会通知与其关联的视图进行更新,实现了数据模型和视图间的双向绑定。 首先,我们需要了解如何创建一个BaseObservable的子类。例如,我们可以创建一个`User`类,...
通过以上方法,你可以在WPF中安全地实现跨线程绑定,确保UI与后台数据的一致性和线程安全性。在实际项目中,根据需求选择合适的方法,但通常建议尽量减少对UI线程的直接操作,以保持用户界面的流畅响应。