又继续读angular文档,发现自己之前理解还是有误。按官方文档的思路service不是属于component的,是属于module的。module才是负责完整领域逻辑的单位。demo的英雄编辑器给我误导了,好像service是从component里拆出去,属于component一样。

问题提出:svg拆分粒度选择

主要问题就是拆分的粒度问题:

1 1个svg图对应1个ng的component

2 1个svg图对应多个compoent, 如<g>里定义若干元素如node,link各自作为组件node-component,link-component

这个和ng和d3本身无关。要看怎么做最符合领域本身的复杂度。然后才是复用的问题。

总的来说:

越是复杂领域复杂问题,越要用大刀阔斧,切记用小刀,过度切分,过度设计

Visualizing Data with Angular and D3的作者的选择是2。他的demo是有点复杂的力导向图,把node link都单独提出去建模了。

是不是也要这样拆分呢?

辨析过程

前端的战场是页面。核心域是"基于dom元素的交互<->更新数据模型"。

D3的计算与展现也是分开的。

如果用ng负责核心域,那么d3就会退居外围service。

ng大概用module负责不同页面的大区(或者顶部/底部这种):每个module内部:

多个component,每1个component负责屏幕上1个特定区域。官方文档摘抄:

每个模块都是一个内聚的代码块专注于某个应用领域、工作流或紧密相关的功能。

组件的任务就是提供用户体验,仅此而已。它介于视图(由模板渲染)和应用逻辑(通常包括模型的某些概念)之间。 设计良好的组件为数据绑定提供属性和方法,把其它琐事都委托给服务。

服务没有什么特别属于 Angular 的特性。 Angular 对于服务也没有什么定义。 

从Domain Driven Design角度:

ng的module是aggregate root,service对应repository factory service,那么component对应的是entry,ts原生class用于value object

从军事领域编制角度看:

module类似本级司令部(战役军团或者高级战术兵团),而component类似下1级的作战编组,承担命令,负责某个地段区域;service是分队,具体实现,更细的class,function类似兵力与兵器。

团以上才称部队,有司政后装,能相对独立地完成任务。

对应ng里module,component都是部队:

module 下辖多个component/service/全套待遇,component也有自己的css/template 负责屏幕上一个地段。

部队负责组织调度分队,分配资源;分队负责执行实现细节。属性方法类似兵力兵器(用值对象表示)

对应 这句话:

组件为数据绑定提供属性和方法,把其它琐事都委托给服务。

我目前理解的系统切分的大的粒度:

每1个作战序列直辖7±2个带HQ的编组比较合适。本级HQ直辖超过10个的没有HQ的分队是明显不合适的,直辖超过10个有HQ的部队,就更离奇了。

这时候,应该像《重构》里说的那样,增加抽象级别。把数量多的部/分队作为自己的下2级,而在下1级建立几个新HQ,把下2级的部/分队分配给新增加的下1级HQ里。

保证自己直接指挥的还是数量有限的下1级HQ,把宝贵的/有限数量的HQ用在这里,不建立过多的HQ,浪费指挥与参谋人员。

这也就是《孙子兵法》里的“分“和”数”了。

我的应用中要有多个svg叠加,更适合用每个component负责一个svg,类似每个作战编组负责一个作战地域,

结论

军队编制 部队(拥有司政后装/承担较完整独立的任务) 分队(函数式的任务)
领域驱动设计 聚合根(拥有相应的service repository 完成较完整的领域逻辑) 实体类,值对象
angular module, component service,class
svg <svg>根节点 <g>下辖的div元素

心得体会:

1表面上是设计问题,技术问题;背后的本质是领域概念切分粒度的分析问题,领域概念理解问题。

2 核心域分析模型的复用:在一个领域和层面想不清楚(D3和angular还没学明白)的时候,从别的自己理解比较清楚的领域,借鉴分析模型(军事指挥中的部队-分队)有奇效。同样之前在军事领域想不清的问题(情报与作训),参考了设计领域的方案(读写分离,CQRS。Command Query Responsibility Segregation)一下就容易理解了。

在复杂度高的领域,长期实践形成的分析模式(行内“条块分割”的通行做法,分工方式/关注点分离的思路),一定是可以借鉴参考的。

前端复杂吧?但是军事更复杂啊。

架构无非就是如何“条块分割”,让系统用起来更顺手,更禁得住各种风险冲击的问题

那么借鉴一下以“条块分割”著称的军队,准没错。(不要借鉴德日这种军阀与地主的l败者组军队,要借鉴鼎盛时期中美苏家的军队架构)

3 不光要有分析模型,设计用的概念模型也要丰富。

"一切皆对象”或者“一切皆函数",“一切皆数据”,抽象粒度太单薄了,语言太贫乏了。

自己脑子也要有军队的部/分队,军团/兵团,基本/高级战术单位,有对应的几级层次才好。

所以增补class上的 namespace,文件级的module之类。不同的语言与框架还提供了 component  blueprint,DDD也增补了聚合根以及配套的(service,repository factory,类似部队的司政后装),确实是有必要的。

比如站在本级的角度,要想着对接上下各2级HQ的方式。对上,要掌握上2级的意图和任务;对下:

命令与事件下1级的HQ部队负责,而兵器兵力数字状态在下2级分队

那么在ng里,本级如果是module:

module->component是命令式指挥,表示目的

component->service是函数式的封装调用,完成实现细节

——在此放一炮:DDD的设计思路如果核心域封装目的,在内;而技术实现在支持域,在外;

那么显然风格应该是  命令式内核,函数式外壳。而不是某些书上说的“函数式内核,命令式外壳”。

内核是领域逻辑的目的,而不是具体实现

军队的级别晋升,不是从基层到高层,而是从实现->意图,从技术->艺术,从控制->指挥,从外围->核心的过程。

基层重视实现过程,用动词抽象,对应函数式

高层重视意图和目的,用名词抽象,对应面向对象与命令式

——函数式用得多的地方,主要也是基础设施,编译器之类。从高层调用的时候,根本不去考虑复杂实现过程。

service作为分队,class作为兵力兵器,不独立承担领域任务,本级没有司令部,所以不判断情况,只负责执行上级明确赋予的战术任务(函数式),本级只负责掌握部队(有错报异常)。分队级的世界观非常符合函数式了:

函数式编程在使用的时候的特点就是,你已经再也不知道数据是从哪里来了,每一个函数都是为了用小函数组织成更大的函数,函数的参数也是函数,函数返回的也是函数,最后得到一个超级牛逼的函数,就等着别人用他来写一个main函数把数据灌进去了。

来自 <https://www.zhihu.com/question/28292740>

恶搞一下:战法(行动)式的分队指挥:

战法式作战在使用的时候的特点就是,你已经再也不知道兵力兵器是从哪里来了,每一个战法都是为了用小战法组织成更大的战法,战法的参数也是战法,战法返回的也是战法,最后得到一个超级牛逼的战法,就等着别人用他来写一个想定把兵力兵器灌进去了。

——其实,用动词建模,不就是活动图么。BPRM

module和component作为部队,拥有自己的司政后装(但不必须):repository,factory,service。承接较独立完整复杂的任务,命令式为主,状态机也会用到。

app->module这个级别,CQRS,领域事件啊该上就上。

——微服务,扁平化,不意味着没有部队,只有分队。高级HQ直接领导数量庞大但琐碎平级的战术分队,那是蒋介石领导的国军(越过自己的战区HQ,总司令指挥到每个战术分队,甚至连)。

所以系统里也不能是app下直接大量的component 大量的class到底。

系统不是多个平级对象互相协作完成任务,而是多个对象在上1级统一指挥下协作,多级HQ形成层次,不要统称class。最终写出来的系统容易变成蒋介石的军队。

不能把负责统一指挥的那个上1级HQ推到设计开发之外,好像“服务编排”之类。那可能才是核心域,写那些脚本才是核心域编码工作。是要精心设计的层次和约束数量的。

必须有要有清晰合理的层级划分。学到的各种设计技巧,因为OO领域抽象语言还是比较贫乏,只能自己强制划分,每级只有某些特性(class分队级没有service,repository这样ER OR的司政后装)

angular组件层次与军事指挥层级职责的联系的更多相关文章

  1. Angular组件——父子组件通讯

    Angular组件间通讯 组件树,1号是根组件AppComponent. 组件之间松耦合,组件之间知道的越少越好. 组件4里面点击按钮,触发组件5的初始化逻辑. 传统做法:在按钮4的点击事件里调用组件 ...

  2. angular,vue,react的基本语法—动态属性、事件绑定、ref,angular组件创建方式

    基本语法: 动态属性: vue: v-bind:attr="msg" :attr="msg" react: attr={msg} angular [attr]= ...

  3. chart.js angular组件封装(ng6)、实战配置、插件编写

    前言 项目需要使用chart.js插件,由于项目是使用angular开发,那么我第一步就是先把chart.js改造成angular组件来使用. 本项目代码都可以在github上下载:项目git地址 a ...

  4. [转]使用 Angular CLI 和 ng-packagr 构建一个标准的 Angular 组件库

    使用 Angular CLI 构建 Angular 应用程序是最方便的方式之一. 项目目标 现在,我们一起创建一个简单的组件库. 首先,我们需要创建一个 header 组件.这没什么特别的,当然接下来 ...

  5. Angular组件之间通讯

    组件之间会有下列3种关系: 1. 父子关系 2. 兄弟关系 3. 没有直接关系 通常采用下列方式处理(某些方式是框架特有)组件间的通讯,如下: 1父子组件之间的交互(@Input/@Output/模板 ...

  6. angular -——组件样式修改不成功

    angular组件样式修改不成功! 自己定义的css可以成功 组件的不行 style在模板字符串里 直接没有 class 是显示的 但是样式不生效 加上面 即可,为什么?我也不太清楚.有知道答案的请回 ...

  7. 手把手教你搭建自己的Angular组件库 - DevUI

    摘要:DevUI 是一款面向企业中后台产品的开源前端解决方案,它倡导沉浸.灵活.至简的设计价值观,提倡设计者为真实的需求服务,为多数人的设计,拒绝哗众取宠.取悦眼球的设计.如果你正在开发 ToB 的工 ...

  8. angular组件间的通信(父子、不同组件的数据、方法的传递和调用)

    angular组件间的通信(父子.不同组件的数据.方法的传递和调用) 一.不同组件的传值(使用服务解决) 1.创建服务组件 不同组件相互传递,使用服务组件,比较方便,简单,容易.先将公共组件写在服务的 ...

  9. Angular 组件通信的三种方式

    我们可以通过以下三种方式来实现: 传递一个组件的引用给另一个组件 通过子组件发送EventEmitter和父组件通信 通过serive通信 1. 传递一个组件的引用给另一个组件 Demo1 模板引用变 ...

随机推荐

  1. android studio 3.0 安装配置

    1.  安装jdk1.8 2.复制android sdk  设置代理  mirrors.neusoft.edu.cn  端口 80 http代理  更新sdk  安装  android support ...

  2. SQL Server 2008 R2 超详细安装图文教程

    一.下载SQL Server 2008 R2安装文件 ed2k://|file|cn_sql_server_2008_r2_enterprise_x86_x64_ia64_dvd_522233.iso ...

  3. 后台维护常用SQL

    OU.库存组织与子库存 select hou.organization_id ou_org_id, --org_id hou.name ou_name, --ou名称 ood.organization ...

  4. asp.net onclientclick事件刷新页面问题解决

      做网页经常要和JavaScript打交道,经常要用JavaScript做一些客户端的验证,但是如果我们的按钮用的是HTML控件的话,验证通过后无法调用后台代码,如果用服务器端控件,验证不通过有要刷 ...

  5. Java设计模式应用——桥接模式

    性能管理系统中,数据产生后需要经过采集,汇聚,入库三个流程,用户才能查询使用. 采集可以是snmp采集,也可以是ems采集:汇聚可以使storm汇聚,也可以是spark汇聚:入库可以是hdfs入库,也 ...

  6. 好用的firefox浏览器、geckodriver驱动的版本组合(55 和 0.19.1)

    试过很多的firefox浏览器版本和geckodriver的组合,有时候好用,有时候不好用,现在确定了一个好用的版本组合,记录一下: firefox:版本55,而且此版本可以用firebug geck ...

  7. 怎样把QQ群降级(1000人降到200或500人,500人降到200)

    怎样把QQ群降级(1000人降到200或500人,500人降到200)QQ群只有升级的选项,没有降级选项,一旦升级为1000人,就无法直接降级为200人或500人,建群时选择了500人也无法降到200 ...

  8. php mysqli query 查询数据库后读取内容的方法

    php mysqli query 查询数据库后读取内容的方法 <?php$mysqli = new mysqli("localhost", "my_user&quo ...

  9. CP2102

    1概述 CP2102其集成度高,内置USB2.0全速功能控制器.USB收发器.晶体振荡器.EEPROM及异步串行数据总线(UART),支持调制解调器全功能信号,无需任何外部的USB器件.CP2102与 ...

  10. VC++ 删除一个文件目录下的所有文件以及目录

    BOOL DoRemoveDirectory(CString chrDirName); BOOL ReleaseDirectory(CString chrDirName) { BOOL bRemove ...