自言自语


2015-04-13

根据Eric的理论,业务层将细分为两个层次:应用层和领域层。

聚合圈出一个范围,在这个范围中,对象无论在哪个生命周期,保持不变性。

ForumThread和ForumMessage的关联关系必设定成单向的,而不是双向的。

领域模型的工厂属于应用层,也就是还是应该处于业务层的,这样好处很多,业务层设计根本无需从Hibernate等持久层框架获得,而是从自己的工厂获得。

DDD和设计模式一样,不是一种新的理论,而是实战经验的总结,使用面向对象技术和分层架构来解决问题,而不是依赖数据库。

目前很多人对软件的思想还是焦点落在:完整的功能,觉得一个软件功能越完整越好,其实关键还是架构的灵活性,就是前者,基础架构好,功能添加只是时间和工作量问题, 但是如果架构不好,功能再完整,也不可能包括未来所有功能,软件是有生命的,在未来成长时,更多功能需要加入,但是因为基础架构不灵活不能方便加入,死路一条。

PUT用来创建一个资源或覆盖原来存在的资源:

创建新资源,只要提供一个新的URL即可:

覆盖原来的资源,只要提供已经存在的URL即可:

PUT的处理,不是通常的UPDATE,修改,具体说不是对一个对象的内部值进行修改,而是把这个对象替换。

POST通常用来实现append追加和更新update一个资源。

PUT相当于X=5赋值;而POST相当于X++;

如果一个对象需要基于原来旧对象读了再改,那么按照值对象定义,这个对象大部分就不是一个值对象,是我们建模时就搞错了。


2015-04-14

框架会主动“侵入”编程过程,要求开发人员按照框架要求进行相应编程,通过功能约束达到无形的设计约束。

好的框架应该能帮助快速高效率开发软件,但是对代码侵入性又很小。

应用代码和框架需要交互通讯的地方必须采取松耦合的方式,比如配置和元注解等方式。

C4模型:context上下文场景, container容器, component组件 和 classe类,意思指一个软件架构是由这些模型呈树形结构组成。

关注代码仍然是大多数软件开发生命周期中关注的焦点,这是有一定道理,因为代码是最终交付。但如果你不得不向别人解释关于系统是如何工作的,你会从代码开始解释吗?

4+1视角架构模型:这种模型是基于使用者的多个不同视角出发。这种多视角能够解决多个”利益相关者”关心的问题, 利益相关者包括:最终用户、开发人员、系统工程师、项目经理等, 能够分别处理功能性和非功能性需求。这些视角都是使用以架构为中心 场景驱动和迭代开发等方式实现设计的。

主要是jivejdon的com.jdon.jivejdon.model下如ForumMessage是主要领域核心模型,它具体实例比如我们讨论的这个帖子在内存中存在一个, 当你第一次发这个帖子时,jivejdon除了在数据库中创建一个ForumMessage记录外,还在内存中加载一个ForumMessage实例对象, 以后,我们关于这个帖子讨论回复,基本是基于加载在内存的这个ForumMessage实例对象进行的,我们发出的Http请求是直接和这个ForumMessage实例对象交互, ForumMessage实例给我们Http响应,由ForumMessage实例自己维持自身和数据库中同样帖子数据一致性,而通常我们都是在一个Http请求响应中直接操作数据库的。

内存中的ForumMessage实例象一个司令部,它接受到我们的http请求后,根据业务规则,再分析成各种细节命令到其他地方,如数据库保存等技术架构,这个细节命令是事件。

WEB-INF/urlrewrite.xml这个组件配置起作用,寻找只有/的配置能找到相应的.shtml,再到WEB-INF/STRUTS-CONFIG.XML寻找相应的action。

可能是JSP方面错误,查看tomcat/logs/localhost_accessXXXX日志是否有错。

定位错误是哪个Jsp,比如根据approvedThreadListTags_jsp.java:1169可以认为是approvedThreadListTags_jsp.java的1169行出错, 可以在tomcat/work目录下找到approvedThreadListTags_jsp.java这个文件,实际是approvedThreadListTags_jsp的Java文件。

approvedThreadListTags_jsp是一个辅助Jsp,不够健壮估计有一个标签数据,可以删除不执行。

实施DDD,CQRS读写分离是必须的架构,事件驱动是缺少不了的,我当初开发JiveJdon也曾经碰到过你这样的问题, 你可以从JiveJdon 4以前的版本看到这个问题,后来在Jdonframework引入事件驱动后,才更好地将BO也就是领域对象和Service等等隔离开。

这之中经历最大的开发方式转变就是:从过去Service+数据库为主的驱动方式,也就是行为用Service,状态用数据库, 这种方式相当普遍,坏处在其他帖子已经谈到了,但是搞了几年这种方式,已经习惯了,改为由领域对象统管封装行为和状态(原来是分散的), 就象一群孩子平时野惯了,没有人管,现在多了一个领域对象BO来封装统管,要么管得太死,成了一个大BO死BO,要么管不住,本来属于同一业务逻辑的行为和状态还是分散开来。

过去数据库驱动开发,也就是首先从需求中找出实体表;而MDD模型驱动开发则是从需求中直接找出领域模型的实体,两者有些类似,都是静态的,但是有本质区别。

聚合根不能太多,Forum和Thread关系如同DDD一书中Car和Engineer的关系,用户User在当前上下文中应该服从与业务根。


2015-04-15

适合有状态或者称可变状态的业务场景,如果用DDD术语,适合聚合根,具体案例如订单,订单有状态,比如未付款未发货,已经付款未发货,已付款已发货, 导致订单状态的变化是事件行为,比如付款行为导致订单状态切换到”已经付款未发货”。

1.用数据表一个字段来表示状态,比如1表示已付款未发货,2表示已付款已发货,然后用户来一个请求用SQL修改。

2.用ORM实现,比如Hibernate JPA来修改状态,虽然不用SQL了,但是Hibernate的悲观锁和乐观锁也让人抓狂。

3.彻底抛弃数据库,直接在内存缓存中进行修改,使用Java的同步锁,性能还是不够,吞吐量上不去。

4.Actor模型。

区分不变与可变,也就是区分无态和有态,也就是区分实体(可变)与值对象(不变),是统领一切的编程法门(无论是多线程还是分布式)。

由于目前操作系统(尤其是Linux)和程序语言的限制(Java/C/C++等),线程无法实现大规模的并发事务。 一般的机器,要保证性能的话,线程数量基本要限制几百(Linux上的线程有个特点,就是达到一定数量以后,会导致系统性能指数下降。

事件是一个语义词,用事件模式编程,能够更符合日常生活中事件用语,比如XXX发生事件了,事件的发生是随机的,那么响应处理也是随机的,事件一词的背后本质就是异步。

从以人为中心的软件角度来看,事件巧妙地打通了业务需求和软件实现之间的鸿沟,既准确表达需求中概念,又能实现高性能并发,充分利用多CPU。

如果从以CPU机器为中心的软件角度看,事件和线程没有什么区别,用脚趾头都能想通,不知为何还有人要去证明什么?无非是想把程序员绕进以CPU机器为核心的僵化思维体系而已。


2015-04-17

异步Message是目前我们已知架构中最松耦合的一种方案


2016-01-05 应用层:定义软件可以完成的工作,并且指挥具有丰富含义的领域对象来解决问题,保持精练;不包括业务规则或知识,无业务情况的状态。 领域层:负责表示业务概念、业务状态的信息和业务规则,是业务软件核心。

nk3310 /
Published under (CC) BY-NC-SA in categories other  tagged with other jivejdon jdon