javaweb 各层理解

许多设计良好的web应用,可以被按职责分为四层。这些层次是表现层、持久层、业务层、和域模型层。每一个层次都有其独特的职责,不能把各自的功能与其它层次相混合。每一个应用层都应该和其它层隔离开来,但允许使用接口在层间进行通信。我们开始来看看每个层,并讨论一下它们各自都应该提供什么和不应该提供什么:

1. 持久层(Persistence layer–DAO–hibernate)

所谓持久,就是把数据保存到可以永久保持的存储设备当中。一般来说,持久更为直接的理解就是对数据库的各种操作,如增加,删除,修改,查询,更新等操作。 持久层,就是把持久的动作封装成一个独立的层,这是为了降低功能代码之间的关联。创建一个更清晰的抽象,提高代码的内聚力,降低代码的耦合度,从而增强代码的要劳动局生和可重用性。 持久层可以封装数据访问细节,为大部分业务逻辑提供面向对象的API。它是一种松散耦合,使持久化不依赖于义愤数据库和上层业务逻辑来实现。我们在设计代码的时候,应该避免在业务逻辑代码中混杂数据访问代码。

DAO,即持久层数据访问对象。利用来抽象和封装所有对数据源的访问,由DAO来管理各种数据源的连接以便于检索和存储数据。DAO一般由业务对象,数据访问对象,数据源和值对象组成。通过DAO实现了数据访问逻辑的抽象与实现细节的封装,只对外提供一个抽象化的数据访问API。我们通过调用API的方法就能实现对数据库的操作。而不必再去理解具体是怎么对数据库进行操作的。这样由于业务操作和数据访问实现分离,也使得开发人员的专业划分成为可能。 在DAO中业务对象仅仅包含与本领域相关的逻辑对象和算法就可以了。针对不同的数据库提供各自的数据访问代码,可以通过定义一个调用接口,针对该接口实现不同数据的数据访问。这样就可以避免对具体实现的依赖,在以后数据库变更时,不用改实现的代码。 Dao层是可以使用Hibernate连接数据库、操作数据库(简单的增删改查)。其和DAO设计模式还不完全是一个概念,我们此处的Dao层中不包含实体类的描述,这部分写在域模型层: DAO设计模式一般分为几个类:

1.VO(Value Object):一个用于存放网页的一行数据即一条记录的类,比如网页要显示一个用户的信息,则这个类就是用户的类。

2.DatabaseConnection:用于打开和关闭数据库。

3.DAO接口:用于声明对于数据库的操作。

4.DAOImpl:必须实现DAO接口,真实实现DAO接口的函数,但是不包括数据库的打开和关闭。

5.DAOProxy:也是实现DAO接口,但是只需要借助DAOImpl即可,但是包括数据库的打开和关闭。 6.DAOFactory:工厂类,含有getInstance()创建一个Proxy类。

ref:http://blog.csdn.net/xiazdong/article/details/6895465/

2. 表现层(UI Layer –Presentation Layer–struts-action层 )

action层负责选择不同的展示UI,为了保证系统能够在不同的UI界面做移植,action不要涉及业务逻辑。 一个典型的web 应用的末端是表现层。许多Java 开发者都知道Struts提供了什么东西。然而,太多时候,耦合代码比如业务逻辑被放进org.apache.struts.Action中。所以,我们先总结一下Struts之类的框架应该提供什么。

下面就是Struts 的职责所在:

扫描二维码关注公众号,回复: 3117338 查看本文章

1.管理用户的请求和响应

2.提供一个控制起来将调用委托到业务逻辑和其他上游处理

3.将来自于抛出例外的其他层的例外处理到Struts Action 中

4.组装可以在视图中表现的模型对象

5.执行UI 校验 下面是一些经常可以使用Struts进行编码但是不应该和表现层关联的事情:

    1.直接和数据库交互,比如JDBC 调用

    2.与应用相关的业务逻辑和校验

    3.事务管理 在表现层中引入这些类型的代码将导致类型耦合和维护负担。

3. 业务层(Bussiness Layer –service-spring-beanFactory)

Service层:引用对应的Dao数据库操作,在这里可以编写自己需要的代码(比如简单的判断)。 service层是调用各种dao的业务操作,比如你有一个业务是 添加,然后修改。 那么你分别调用dao的添加和修改操作,包括里面的一些数据转换,逻辑判断都放到service层,dao只是单纯的增删改查。 而且事务一般会放到service层。 其中Service层和DAO层由于可能都会对数据库进行操作,其具体区别为: dao和service对应 一般情况下,Hibernate DAO只操作一个POJO对象,因此一个DAO对应一个POJO对象。 Service层是为了处理包含多个POJO对象(即对多个表的数据操作)时,进行事务管理(声明式事务管理)。Service层(其接口的实现类)被注入多个DAO对象,以完成其数据操作。

Service之有无 这一点我的看法未必正确,我的脑海现在有两种构建业务层的模式:

模式1是Service + DAO,即DAO中只做CRUD及类似的简单操作(称之为功能点,不包含业务逻辑),Service中通过调用一个或多个DAO中的功能点来组合成为业务逻辑.Service的数量应该由功能模块来决定。 在这种模型中业务逻辑是放在Service中的,事务的边界也应该在Service中控制. 当然,直接在Service中控制事务会引入非业务逻辑的代码,幸好Spring的AOP可以解决这个问题,这也是引入Spring的原因之一. 如果说到缺点,就在于对某些对象的操作就是简单的CRUD,Service层显得累赘.

模式2是Service + BO, 而BO = DAO + 业务方法, 在原先DAO的基础上添加业务方法,形成BO对象。需要注意的是BO中的业务方法往往是针对一个实体对象的,如果需要跨越多个实体对象,则方法应该放在Service中。 举例来说,一个简单的银行帐户管理系统,创建帐户这个BO对象,里面可以有修改密码,取钱等业务方法(不难看出,这些方法都只对单个帐户对象进行操作)。现在需要添加一个转账方法,就应该放在Service中。 这里Service和BO的关系是什么样的呢?再举一例:以国家行政机关为例:粮食局负责收粮,卖种子等,建设部负责审批土地买卖,建设公路等,这都是行政部分份内的事儿。突然某地发了水灾,救灾时需要粮食局开仓放粮,建设部修建临时房屋,如何协调两个部门?就需要成立专门的救灾委员会,由救灾委员会出面对两个部分的资源进行调拨。这里两个部分就是BO,而救灾委员会就是Service。不知我的意思是否表达准确了,呵呵。 模式1的在划分Service和DAO时界限清晰,但会带来一些无必要的代码。 模式2的划分相对复杂,然而可以提高编码效率。 当然小规模的应用中,没有Service,完全是DAO或BO也是可以接受的。 Service和DAO的接口之有无 接口是一种契约,它可以有多种实现。所以接口之有无取决于具体实现是否需要多样化。如果铁定一种DAO或一种Service只有一种实现,那么抽象出接口的意义不大。然而一些大型应用或许需要DAO和Service的多种实现(比如上面例子中的帐户DAO,可能需要一种Hibernate实现、一种CMP实现和一种JDO实现),为了向上一层隐藏具体实现类,需要采用接口。 隐藏具体实现类的创建过程,这有两种方法:一是实用工厂方法,代价是代码量大(每个DAO和Service一个工厂)。二是使用Spring的IoC,实现依赖注入,不需要写额外的代码,这也是引入Spring的理由之二。

ref:http://blog.csdn.net/njujmj/article/details/5202915

4. 域模型层(Domain model)

软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 Domain层是整个系统的核心层,该层维护一个使用面向对象技术实现的领域模型,几乎全部的业务逻辑会在该层实现。

Domain层包含:

1.Entity(实体): 有一类对象拥有唯一标识符能够跨越系统的生命周期甚至能超越软件系统的一系列的延续性和标识符这样的对象称为实体。

2.ValueObject(值对象) 对某个对象是什么不感兴趣,只关心它拥有的属性用来描述领域的特殊方面、且没有标识符的一个对象,叫做值对象,能被简单的创建和丢弃,生命周期中不会被持久化值对象可以被共享,值对象应该不可变

3.Domain Event(领域事件)

4.Repository(仓储)等

ref:http://blog.csdn.net/johnstrive/article/details/16805121 

参考链接:

http://blog.csdn.net/zcf396720/article/details/51372580

 转载:

https://blog.csdn.net/qq125293177/article/details/52839506  

猜你喜欢

转载自blog.csdn.net/aoocean/article/details/82557529