1、Jdon Framework 6.5 Domain-Driven Design(DDD)开源框架,2011.10,Simplify the Best,JdonFramework = Domain Model + In-memory + Events. JdonFramework = DDD(领域驱动设计) + DCI + Domain Event 或 Event Sourcing 或CQRS 能够在此架构基础上无缝平滑发展成为一个可方便维护、可灵活拓展、可伸缩的中大型系统。 Apache 2.0 开源 JdonFramework(以下简称JF)就是这样一个简单易用 设计理念一直国际领先的轻量J
2、ava框架。,JavaEE多层架构,MVC表现层 struts1.x Struts2 JSF Tapestry Wicket,持久层 Hibernate SQL IBatis NoSQL,服务,业务层JdonFramework,领域模型,JdonFramework特点,DDD : 领域驱动设计,通过突出领域模型作为整个系统的中心作用,以领域模型的设计驱动表现层和数据库的开发设计。IOC或DI:完全自动识别的依赖注射模式,可以完全摆脱类与类之间的依赖关系,大大提高开发效率和重构速度。In-memory Cache:内置缓存自动支持,借助Terracotta能够无缝将应用程序拓展到云计算架构。,E
3、vans DDD,DDD特点,统一语言:一个无处不在(ubiquitous )的语言,项目中所有人统一交流的语言。减少沟通疑惑,减少传达走样。使得软件更加适合需求。 统一领域模型:领域专家和程序员统一使用一种模型,没有数据库数据表等专业软件技术干扰。 专门的业务领域层:领域层除了业务没有其他,没有软件架构 框架等等底层技术。,DDD优点,坏设计:失血贫血模型,将业务逻辑写在Servlet 、Jsp、MVC的Controller、SOA的服务中技术架构驱动数据模型,数据模型只是一个数据的集合。模型对象中只有setter/getter方法,无其它业务方法,称为失血或贫血模型。失血模型导致软件复杂时
4、,可扩展性和性能大幅度降低,难于提升。随着时间推移,开发效率降低。,JF架构特点,领域模型驱动技术架构; 领域模型是富充血模型,类似人类的DNA,是各种重要事件导向的开关。 用户触发事件,事件直接激活领域模型的方法函数,再通过异步事件驱动技术活动,如存储数据库或校验信用卡有效性等。 2009年推出Domain Model + In-memory + Events. 2011年Martin fowler的LMAX架构 推荐In-memory + Event Sourcing架构。,JF的五种模型组件,一. 实体聚合根对象 元注释 Model; 二. 服务Service 元注释 Service;
5、三. 普通类组件构件 Component; 四. 生产者Prodcuer-消费者模型 send Consumer; 五. 拦截器 Interceptor, 首先需要导入点 Introduce; All in com.jdon.annotation.*,领域模型和技术组件,Model 领域模型,包括实体模型 值对象和领域服务,与技术架构无关。相当于鱼;生存空间是缓冲器中Service/Component 技术组件架构,用以支撑领域模型在计算机系统运行的支撑环境,相当于鱼生活的水。空间在Context container,例如ServletContext中。两者以Domain Events模式交互
6、:异步 命令。,Domain Events,在Evans DDD实现过程中,经常会碰到实体和服务Service以及Repository交互过程,这个交互过程的实现是一个难点,也是容易造成失血贫血模型的主要途径。Domain Events提出解决方案, JF提供的异步观察者模式为Domain Event实现提供更优雅的解决方案。详细文章见:http:/ Events图,为什么使用事件模型?,事件模型适合将复杂业务领域和复杂技术架构实现分离的不二之选。普通编程是同步顺序执行;事件模型是异步并行执行,大大利用了CPU效率。无锁,无堵塞,所以快。,CQRS(命令查询分离),User interface
7、,Service,Domain,Event/Message BUS,Infrastructure,Query/ Reporting,Commands,Commands,Events,领域事件起点:内存中实体模型,使用DDD从需求中获得实体模型后,使用JF的Model加以标识。 每个实体模型必须有一个唯一标识,如User对象必须有一个userId。 该实体模型必须以Model注解。以Model标注的对象实例将存在缓存中,常驻内存In-memory。 Model public class MyModel private String userId;private String name;,使用An
8、notation激活In-memory,从数据库读取模型数据转换成模型对象时,DDD称为Repository仓储,在这个类上必须加入Introduce(“modelCache”) Around。 这一步确保领域对象每次加载在内存都是唯一的,In-memory。这对于后面使用domain events是必须关键重要步骤,Source: com.jdon.sample.test.domain.onecase.repository.RepositoryImp,Domain Model + Event,Domain Model Model,Other Components Componet,Loggi
9、ng Consumer,GUI MVC Client,Persistence Consumer,async Message,async Message,async Message,Component architecture,Domain Events两种实现,主题topic和Queue队列。 领域模型是生产者;消费者有两种: 1.Consumer;可以实现1:N多个,内部机制使用号称最快的并发框架Disruptor实现。适合轻量;小任务;原子性;无状态。 2.Componet;直接使用普通组件类作为消费者,使用jdk future机制,只能1:1,适合大而繁重的任务,有状态,单例。,Doma
10、in Events 工作原理,Domain Model Model,Consumer Consumer Component,Disruptor 或 Java concurrent Future,Domain Message,Domain Events: 实现第一步,(1) . 使用 Model 和 Introduce(“message”)标注实体类 (2) . 使用 Send(“mytopic”) 标注该实体中的发送方法,Source :com.jdon.sample.test.domain.onecase.DomainEvent,Domain Events: 第一步,Introduce(“m
11、essage”):“message” 表示引入JF配置aspect.xml中消息拦截器: om.jdon.domain.message.MessageInterceptor 通过该配置让该模型类成为消息生产者或发送者。 Send(“mytopic”): “mytopic”是消息topic名称,可自己取,但是和消费者的标注 Consumer(“mytopic”)是一致的,表示生产者将消息发往这个topic中; 在send标注的方法中,你还需要将你要传送给消息消费者使用的数据打包进入DomainMessag对象,该方法的返回类型必须是DomainMessag.,Domain Events: 第二步
12、,(1) 标注消费者Consumer(“mytopic“); (2). 消费者类必须实现接口 com.jdon.domain.message.DomainEventHandler,Source:com.jdon.sample.test.domain.onecase.MyDomainEventHandler,队列Queue原理,Queue mychannel,Send(“mychannel”) 将一个DomainMessage对象放入队列中, 另外一个消费者线程将从队列中获得DomainMessage对象。,消费者注意项,如果有多个消费者订阅了同一个主题Topic,那么这些消费者之间的运行顺序是
13、按照他们的类名字母先后的。如AEventHandler先于BEventHandler先于CEvent等。消费者的主要内容写在onEvent中,可通过event.getDomainMessage()获得生产者你要传递的数据。,返回事件处理结果,如果要返回事件的处理结果,在DomainEventHandler的onEvent方法 将结果设置如event的DomainMessage中,如下: void onEvent(EventDisruptor event, boolean endOfBatch) throws Exception /返回结果 “eventMessage=hello” event.
14、getDomainMessage().setEventResult(“eventMessage=“ + myModel.getId(); ,客户端调用代码,JdonFramework客户端可以是在Web的Servlet或Jsp中调用,也可以在Application调用,如下: /初始化框架 ContainerSetupScript css = new ContainerSetupScript(); css.prepare(“com.jdon.jdonframework.xml“, da); AppUtil appUtill = new AppUtil(“com.jdon.jdonframewo
15、rk.xml“);IServiceSample serviceSample = (IServiceSample) appUtil.getService(“serviceSample“); /得到返回结果“eventMessage=hello” String res = (String) serviceSample.eventPointEntry(“hello“); Assert.assertEquals(res, “eventMessage=hello“);源码见:com.jdon.SampleAppTest,事件Topic主题好处,原子性 Martin fowler :LMAX Archit
16、ecture中认为可替代 传统数据库事务或会话事务。 可将原来一整块事务切分成多个单个事务处理器(消费者) 比如:保存到数据库和lucene文件如果捆绑在一个事务,由于文件保存很慢,导致数据库保存拖延,可切分成两个事件消费者异步实现。见jivejdon的Repository中的SaveMessage.java。,另外一种Queue实现,Send(topic) = Component(topic); 消费者直接是Component(topic) 标注的类,必须实现接口com.jdon.domain.message.MessageListener JF 6.3之前缺省的Domain Events实
17、现。使用JDK的future实现。保留在新版本中。,领域事件模式优点,松耦合业务逻辑能够与技术架构解耦,将”做什么”和”怎么做”分离EDA架构Event-driven Architecture异步事件驱动模式异步懒惰加载Asynchronous Lazy-load 类似函数式语言的懒功能,只有使用时才真正执行。真正可扩展性Scalable通过与JMS结合,可以在多核或多个服务器之间弹性扩展。,事件应用:异步懒加载,即用即取数据,随时运算。 函数功能只有在它的返回结果需要时才真正执行计算,类似erlang Scala等函数式语言。 再也Hibernate LazyInitializationEx
18、ceptions错误烦恼, 没有Session持续打开(Session打开就是数据库连接一直打开,耗费资源,性能杀手) 不需要Open Session in View 反模式,不再需要使用SSH或S2SH组合中,在web.xml配置Spring的OSIV过滤器,这时耗费资源和危险的,特别是嵌套错误抛出时。 可以在MessageListener处集成入JMS,JMS是可伸缩性并带有分布式事务方案,可以保证持久化等事务精确完成。,事件应用:模型的异步 + 懒加载,假设computeCount是一个非常耗CPU的任务,使用并发策略可以消除这种延迟。 public int getMessageCoun
19、t(DomainEvents domainEvents) if (messageCount = -1) if (messageCountAsyncResult = null) messageCountAsyncResult = domainEputeCount(account.getUserIdLong(); else messageCount = (Integer) messageCountAsyncResult.getEventResult(); return messageCount; ,事件应用:异步调用,第一次调用 getMessageCount方法,激活耗时的 domainEput
20、eCount. 方法,这次调用中我们可以不需要范围结果。第二次再次调用getMessageCount将得到前面耗时的计算结果,我们可以通过AJAX实现二次调用。Download Sample Source,可扩展到分布式架构,Domain Model,JMS,Persistence,Send Email,Other Services,Message,Domain Model,Message,Distributed Cache,Distributed Cache,基于领域模型的分布式架构,领域模型 + 分布式缓存 + 存储 + JMS异步 领域模型带着逻辑和数据被分布式缓存如Ehcache +T
21、erracotta分布到多台机器中运行。 领域模型通过JMS驱动技术架构实现功能。 JMS= 集群无单点+分布式事务架构 业务数据装在领域模型中,关系数据库只是用来做存储,NoSQL(Not Only SQL),领域模型数据和数据库数据不高度一致,低延迟。,性能测试结果,下面是基于Jdon框架的开源社区软件 jivejdon测试结果:HTTPadd1 是新增/插入 HTTPedit是编辑/修改 HttP1.2.3 读取和查询功能 他们的响应时间几乎相差无几。 这些功能都只发生在内存中的领域对象上,耗时的数据库写等操作都异步地在事件消费者中实现。,事件模型的注意点,如果说我们普通编程是在一个线程
22、内进行顺序同步编程,那么Jdon框架的事件编程实际是一种并行异步编程模型。普通编程需要花力气让程序并行运行;而事件编程则要注意让其顺序执行。 顺序执行可采取将上一个事件处理结果(DomainMessage)传入下一个事件,然后再进行堵塞等待方式。具体可见Jdon框架开发指南一书。,堵塞系统的问题,在一个堵塞或有锁的系统中, 等待线程将会闲置,这会消耗很多系统资源。 消耗资源的公式如下: 闲置的线程数 =(arrival_rate * processing_time) 如果arrival_rate(访问量达)很高,闲置线程数将会很大。 堵塞系统是在一个没有效率的方式下运行,无法通过提高CPU负载
23、获得高吞吐量。,非堵塞的并发模型 Non-Blocking concurrent,发出调用以后不必立即使用结果,直至以后需要时才使用它。 发出调用后不要堵塞在原地等待处理结果,而是去做其他事情,直至你需要使用这个处理结果时才去获取结果。 被调用者将会返回一个“future”句柄,调用者能够获得这个句柄后做其他事情,其他事情处理完毕再从这个句柄中获得被调用者的处理结果。,JF的无堵塞的并发编程,领域模型发出事件,事件由Disruptor的RingBuffer传递给另外一个线程(事件消费者);实现两个线程之间数据传递和共享。当事件消费者线程处理完毕,将结果放入另外一个RingBuffer,供原始线
24、程(事件生产者)读取或堵塞读取,是否堵塞取决于是否需要顺序了。,并发模型的更高抽象,基于Domain Events的并发策略也许有些底层复杂,如何让程序员更容易方便地开发并发程序呢?Actor Model 类似Domain Events ,消息是异步 非堵塞发送和接受 属于“fire-and-forget”。Disprutor的LMAX团队测试Actor模型是有瓶颈的,所以他们采取Disruptor.DCI ArchitectureDCI易于被理解,它的抽象层次比Domain Events更高,是基于领域和架构的,用DCI来抽象封装事件模型也许是一种易于使用的方式。JF进行了探索。,DCI,数
25、据Data, 上下文(场景)Context, 交互Interactions是由MVC发明者Trygve Reenskaug发明的。让我们的核心模型更加简单,只有数据和基本行为。 业务逻辑等交互行为在角色模型中 在运行时的场景,将角色的交互行为注射到数据中。领域事件是在不同场景下由实体发出事件驱动服务,场景隐含,事件代表场景出头牵线。,模型注入,Jdon框架能够在运行时将 Domain Events注射到领域模型中,有些类似Mixin. Domain Events是角色的交互行为,而按照DCI要求,角色在需要的上下文中被分配(注入)到数据模型对象中。Domain Events和DCI在机制上是一
26、致的。,DCI :数据,领域模型是DCI的数据,尽可能简单基本,Source: com.jdon.sample.test.domain.simplecase.MyModel,DCI : 交互,这是DCI角色类,封装了领域事件的发送行为,实际也是事件的生产者。,Source:com.jdon.sample.test.domain.simplecase.MyModelDomainEvent,DCI : 场景,在运行时的场景,角色将被注射进入领域数据模型:/当从仓储获得模型对象时,事件已经被注入MyModel myModel = repository.getModel(new Long(100);/
27、通过模型发出事件。myModel .myModelDomainEvent.asyncFindName(this);以上代码只有在运行时有效,角色 MyModelDomainEvent 将被自动注入 MyModel。 完整案例下载: SimpleJdonFrameworkTest.rar,无领域事件的DCI,模型中拥有可被注入领域事件,模型在任何地方都能发出事件;但是缺点是我们必须首先从仓储中获得这个模型对象。 模型中如无领域事件,那么模型就是动作的被动接受物,我们在场景中对其注入后再发出事件。 右边是一个无领域事件的数据模型。,Role,这种情况下,角色必须有一个接口,否则无法实现Mixin功
28、能,Context,com.jdon.domain.dci.RoleAssigner,com.jdon.domain.dci.RoleAssigner 是一个角色分配器,可以向任何模型中注入任何接口 (Mixin) 当使用RoleAssigner, 我们就没有必要从带有元注释 Introduce(“modelCache”) 和 Around的仓储中首先获得一个模型对象。 RoleAssigner可以手工对任何一个模型对象从外部进行事件注入或角色分配。 提高了使用灵活度。,两种不同风格的DCI,如果我们已经Hold住了一个领域对象,那么就直接通过其发出领域事件实现功能;比如模型的修改。否则,我们
29、创建一个上下文Context, 在其中通过RoleAssigner将角色接口注入到领域对象中。比如模型新增创建或删除。(对象不能自己创建自己)。,client,Model,Model,client,Context RoleAssigner,Component,Component,Mixin,Create,Modify,Event,Component,Component,inject,并发编程的易于使用,JF 6.5版本为推广适合多核CPU的无堵塞并发编程范式进行了探索。 使用了Domain Events和DCI等不同抽象层次对并发编程进行了封装,从而降低开发者使用并发编程的难度。 DCI和四色
30、原型等软件分析方法可以顺利对接,抽象层次最高,直接面向业务。 帮助普通程序员在只考虑业务的不自觉情况下直接使用无堵塞并发编程。,Example for DDD and DCI,DDD Entity Model,roles-and-responsibilities,职责驱动开发的要点:Knowing what; doing what;deciding what.Robot know what? Do what? Robot 通过其传感器能够感觉feel 看见see 听见hear Feeling seeing 和 hearing 是作为一个智能机器人这个角色必须具备的功能职责。,职责应该放在哪里?
31、,是不是将所有职责都作为实体Robot类的方法呢?如图: 这将会造成一个庞大臃肿的实体对象。DCI 说 : 不,DCI,职责就是DCI中角色的交互行为。在需要的场景context中这些职责行为能够被注入到数据模型中。,Robot的JdonFramework实现,详细实现描述见文章: DDD DCI and Domain Events examplerobot.zip Robot 源码下载。,JdonFramework特点,DDD : 领域驱动设计,通过突出领域模型作为整个系统的中心作用,以领域模型的设计驱动表现层和数据库的开发设计。IOC或DI:完全自动识别的依赖注射模式,可以完全摆脱类与类之
32、间的依赖关系,大大提高开发效率和重构速度。Cache:内置缓存自动支持,借助Terracotta能够无缝将应用程序拓展到云计算架构。,Ioc/AOP轻量容器,依赖或或者控制关系的反转注射(Ioc模式) 通过配置/微容器解决POJO调用关系。 高度灵活和松耦合,实现对象的可更换。面向方面编程(AOP) 提供在不改变原来架构基础上,动态增加/更换一些普遍功能。 Out-of-the box,JF注射和拦截架构,Model:模型中可以通过字段的Inject将其他类注射进入,包括Component类。被注射的类如果有Introduce,将再次引入拦截器。Component:技术架构中组件可以通过构造器
33、直接注射进入其他Component组件,被注射的类如果有Introduce,将再次引入拦截器。,灵活的注入和拦截,依赖注入Dependency Injection(DI or IOC) Service or Component 能够进行彼此注入,通过其类构造器 (不支持 setter方法注入).Service or Component也能被注入到 Model 领域模型中,或者使用 domain events.面向方面编程Aspect-oriented programming(AOP)使用Introduce: Service or Component 能够将彼此引入作为拦截器. Model 能引
34、入任何 POJO 或 Component作为它的拦截器,Model内部机制,Client xx.getA(“a”),A Model,Interceptor for A with Introduce,B that need implements interface and has Introduce,Inject proxy of B,Interceptor for B with Introduce,Cache container,C,Inject proxy of c,Component In Context Container,interceptor,模型内注射,Component内部机制,
35、Client xx.getA(“a”),A Service,Interceptor (poincut=service),B that need implements interface Component,Inject proxy of B,Interceptor for B with Introduce,Context container (ServletContext),如何调用一个有依赖的服务?,AOP Introduce使用方法,Introduce(名称) 为当前类引入拦截器,可以用在Model或Component中,名称是拦截器的Component(名称). 例如Introduce(
36、“c“) - Component(“c”)在当前类具体方法上使用Before After和Around三种拦截器激活的方式。注意使用Around对拦截器有特定写法要求,其他无。,Introduce 引入拦截器,被Introduce 引入的拦截器,Component(“c“) public class C /被拦截器的Input参数将注射到inVal中public Object testOne(Object inVal) . /testOne 方法return 结果将被注射到被拦截器的return中/被拦截器的方法myMethod2返回值将被引入此方法的inValepublic Object t
37、estWo(Object inVal) ,Introduce的Around,如果某个类似于Introduce的Around,那么对被引入的拦截器有特殊要求写法:Interceptor(“aroundAdvice”)/1. 需要表明自己是Inteceptor public class AroundAdvice implements MethodInterceptor /2.需要实现 org.aopalliance.intercept.MethodInterceptor接口/3.完成接口的Invoke方法public Object invoke(MethodInvocation invocatio
38、n) throws ThrowableObject o = invocation.proceed();/在此方法前后写包围around代码。,JF拦截器第二种写法,/1. 指定被拦截的类是Component(“a”)和Component(“c”) Interceptor(name = “myInterceptor“, pointcut = “a,c“) public class MyInterceptor implements MethodInterceptor /2.需要实现 org.aopalliance.intercept.MethodInterceptor接口/3.完成接口的Invok
39、e方法public Object invoke(MethodInvocation methodInvocation) throws java.lang.Throwable 被拦截器的类没有特别规定写法,只要标注Component(“a”)就可以,至于拦截a的什么方法,在拦截器invoke中实现。该方式将拦截定义在拦截器这里,和Introduce定义正好相反。,自动注射的两个优势,完全可定制:面向对象编程之父Grady Booch 说:对象最伟大之处在于其可被替代(The great thing about objects is they can be replaced) 而JF伟大之处是帮助你
40、替代这些对象,甚至包括JF本身。无需对象创建:颠覆对象使用之前必须创建的基本定律,正象无需关心对象销毁一样,您可以无需关心对象创建。,JdonFramework特点,DDD : 领域驱动设计,通过突出领域模型作为整个系统的中心作用,以领域模型的设计驱动表现层和数据库的开发设计。IOC:完全自动识别的依赖注射模式,可以完全摆脱类与类之间的依赖关系,大大提高开发效率和重构速度。Cache:内置缓存自动支持,借助Terracotta能够无缝将应用程序拓展到云计算架构。,第三个特点: Cache,业务层可直接操作缓存,便于将业务状态保存到缓存中,实现以对象状态替代数据库进而提升性能的设计目的。Jdon
41、缓存在具体架构应用时可灵活设置在表现层/业务层/持久层等位置,通过拦截器使表现层访问缓存(依据缓存越提前越快原理);,JF缓存架构,Presentation,Domain,Persistence,CacheInterceptor In aspect.xml,DomainCacheInteceptorIntroduce(“modelCache”),JF缓存特点,只要标识Model的实体,在表现层Jsp页面再次使用时,将自动直接从缓存中获得,因为在中间业务层和表现层之间Jdon框架存在一个缓存拦截器CacheInterceptor,见框架的aspect.xml中配置。 为了能够在业务层也能够使用缓
42、存,需要在业务层后面的持久层或Repository中手工加入缓存的Annotation标签。,In-Memory Model,当我们从仓储获得一个模型对象时,这个仓储类必须用元注释Introduce(“modelCache”) ,它的获得模型对象的方法必须有Around。这样就自动激活模型的缓存功能。 当下次再从仓储获得这个模型对象时,将自动从缓存中查找,如果有直接返回。 我们获得的这个模型对象已经被自动注射了领域事件(如有Inject)。,使用Annotation激活Cache,在模型对象被创建或从数据库读取重构的Repository仓储处,必须加入Introduce(“modelCache
43、”) 注解, 这一步对于使用domain events是必须关键重要步骤,Cache高可伸缩性,1. 使用JF开发的应用系统可无缝平滑升迁到EJB架构。同时支持POJO Services和EJB混合运行,可接驳原有的EJB系统。2.使用Terracotta透明轻量地分布式云计算内存产品,可以无缝将应用程序升级到云计算平台。可根据分布式CAP原理灵活架构。 (http:/ ),在Web中启动框架,如果全部使用元注释,没有使用XML配置,则无需启动步骤。 在Web.xml中配置xml文件所在位置,如在com.jdon包下,前面加包名:modelmapping-config jdonframewor
44、k.xml com.jdon.container.startup.ServletContainerListener ,在普通java应用中使用,AppUtil appUtil = new AppUtil(); / xxx is value of Service(“xxx”) annotation on class. XXXService xxxService = appUtil.getService(“xxx”); xxxService.method();如果有jdonframework.xml配置: AppUtil appUtil = new AppUtil(“com.jdon.jdonfr
45、amework.xml“);,JdonFramework其他特点,快速开发,简化代码,模型的CRUD操作流程固化,模板化编程。(只支持struts1.x)CQRS模式:命令查询的责任分离Command Query Responsibility Segregation 。 模型状态的操作和批量查询分离,提供专门的批量查询支持。支持远程胖客户端,MVC控制器配置 jdonframework.xml(struts1.x),Jdonframework MVC(struts1.x),View,View,Controller Jdonframework.xml,ActionForm,Model,Servi
46、ce,MVC流程CRUD快速开发,应用软件中大量底层基础功能是CRUD (创建读写修改和删除),调试耗时而且不稳固。 传统开发中,一个模型的CRUD需要多个流程实现,没有技术含量的烦琐和麻烦。 JF将CRUD流程简化捆绑在配置,CRUD中只要创建功能调试正常,其他也就正常,无须烦琐调试。提高基础功能的调试时间。 (只支持struts1.x),CQRS模式:批量查询,模型状态操作和查询实现分离。 批量分页查询也是应用软件中经常需要开发的基础功能。性能差是主要原因。 JF可以做到: 1. 缓存优化,性能卓越 2. 开发流程简化,少量代码就可以完成 3. 自动分页支持。,性能优化:批量查询解决方案,
47、提供大批量大数据分页查询的简单解决方案 批量查询设计两个宗旨:1. 尽量减少数据库访问,减少数据库负载和I/O性能损耗。2.由于J2EE是一个多层结构,尽量减少在多个层次之间传送的数据量。减少传送损耗。3.跨层解决;分层实现:不能由界面直接驱 动数据库操作(服务器分离部署时增加网络通讯)。,支持远程胖客户端,支持Java编写的各种胖客户端Fat Client,如Swing Applet SWT等; 支持基于Http的远程调用RPC; om.jdon.bussinessproxy.remote包。 在C/S结构下,无需重写Domain Object或Service;同时无缝支持B/S结构和C/S
48、结构; 使用JF ,远程专用客户端可穿透防火墙直接访问EJB。 支持Hessian远程访问RPC,将支持RestFul。,REST in JdonMVC,Include jdonMVC example download: SimpleJdonFrameworkTest.rar,JF在软件生产位置,需求Use case分析 四色原型(彩色UML) DDD领域驱动设计 DCI DDD DCI CQRS介绍 DDD领域驱动设计 CQRS和DCI架构都是目前软件领域热门主流最新技术。,总结,项目中文网址:http:/ JiveJdon.基于JF的中型社区程序 JdonMVC 是一个基于JF的REST MVC开源框架 English: http:/www.jdon.org/ Gihub:https:/