《OA系统项目开发7575.docx》由会员分享,可在线阅读,更多相关《OA系统项目开发7575.docx(61页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、 OA系统项目开发UML小结以及基于领域模型的系统设计初步UML不是OOA/D 也不是方法,它仅仅是一种图形表示法。其目的就是让人能看懂你的东西。每一种图,都相当于一种角度。不同的图就是从不同角度来观察系统。比如交通图和行政区划图,从不同角度观察中国。 必要性是画图的原则,虽然有这种关系,但不一定要画出来,如果非要画出来,则应考虑不要影响图形的美观。 活动图活动图表示的是一种流程。例子:顺序图顺序图的目的是为对象分配职责,而不是步骤的罗列。上图中,ActionServlet是没有必要画出来的,它是一个很稳定,也不是我们自己提供的,没有必要来说明它的对象职责。插在这里显然多余.如下图这样就可以了
2、:用例和用例图用例的定义:文本形式的情节描述。 用例用于需求的发现和记录,它会影响后续的OOA/D工作 用例不是用例图。用例图不重要,用例描述很重要。 用例尽量不要用名词命名,尽量以动词开头,比如:管理商品。用例一般是用于功能性的需求而非性能性需求。编写用例时,在基本路径(即主成功路径)中,只书写主要的成功事件,而可能出现的其他情况(如找不到用户)应该写在扩展点中。 用例粒度:比如:是把管理用户当做用例还是把添加用户和删除用户分别当做两个用例。确定用例的粒度时,应该考虑描述这个用例的基本路径需要几个步骤。十步以内,七八步比较合适。一个典型的用例描述一个典型用例图其中销售经理和收银员之关系是泛化
3、关系,即经理拥有收银员所拥有的一切用例。另外还有其独有的用例。类图类图允许我们标记静态内容及类之间的关系,它是UML中最重要的图形,可以在任何时候尝试使用类图。不要使用类图描述所有的细节,保持类图的简单。UML中主要有三种类:边界类、控制类和实体类边界类位于系统与外界的交界处,例如窗体、报表、以及表示通讯协议的类、直接与外部设备交互的类、直接与外部系统交互的类等。通过用例图可以确定需要的边界类,每个Actor/Use Case对至少要一个边界类,但并非每个Actor/Use Case对要唯一的边界类。实体类可以通过事件流和交互图发现。通常每个实体类在数据库中有相应的表,实体类中的属性对应数据库
4、表中的字段。控制类是控制其他类工作的类。控制类可以被多个用例共用。其他类并不向控制类发送很多消息,而是由控制类发出很多消息。 类图中,要画出类之间的关系UML中继承、实现、依赖、关联、聚合、组合的联系与区别继承 (也叫泛化)指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;在Java中此类关系通过关键字extends明确标识,在设计时一般没有争议性;实现指的是一个class类实现interface接口(可以是多个)的功能;实现是类与接口之间最常见的关系;在Java中此类关系通过关键字 impl
5、ements明确标识,在设计时一般没有争议性;依赖可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是B类的变化会影响到A;比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖;表现在代码层面,为类B作为参数被类A在某个method方法中使用;关联他体现的是两个类、或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友;这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的、关联可以是单向、双向的;表现在代码层面,为被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一
6、个类型为被关联类B的全局变量;聚合聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU、公司与员工的关系等;表现在代码层面,和关联关系是一致的,只能从语义级别来 区分;组合组合也是关联关系的一种特例,他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;比如你和你的大脑;表现在代码层面,和关联关系是一致的,只能从语
7、义级别来区 分;总结:继承、实现体现的是类与类、或者类与接口间的纵向关系,不易混淆;其他的四者关系则体现的是类与类、或者类与接口间的引用、横向关系,这几种关系都是语义级别的,所以从代码层面并不能完全区分开来;例如在关心汽车的领域里,轮胎是一定要组合在汽车类中的,因为它离开了汽车就没有意义了。但是在卖轮胎的店铺业务里,就算轮胎离开了汽车,它也是有意义的,这就可以用聚合了。总的来说,后几种关系所表现的强弱程度依次为:组合聚合关联依赖示例一关联之特殊示例,下图表示一种树形结构类图,可以用如下代码实现Public Class Node Public ID; Private Node parent; P
8、rivate Set children;示例二:已经在关联中表明了 Document 具有一个User类型的字段 Creator,故不必在Document中再写出Creator了。示例三:由于User是另一个复杂的概念,所以要建立关联,而不是把User也作为一个简单的属性(如name那样)不要把复杂的领域概念建模为属性。 示例四:Student 与 class 之间是双向关联关系,当然也可以说成是student依赖class,因为没有class,student是不能编译通过的。但画图并不是所有存在的东西都要画出来,这里表示成关联关系更为贴切些。另外,关联指的是关心对方的结构,如果对象A只是用一
9、用对象B的某个方法,比如Collections.sort(), 这显然是依赖而非关联。基于领域模型的系统设计初步设计时重要原则: 低耦合,高内聚. 尽量降低对不稳定对象的依赖。对于非常稳定的东西,比如JDK的核心类库,尽可以随便依赖它。 不要依赖于正向工程和逆向工程,如果你要让其从图形生成代码,则你不得不在图形中注意各种细节,那不如你自己写代码。 图形是为了抽象出逻辑主干,方便人理解,它不能替代详细完整的文字描述。系统的核心价值领域模型的价值不在于它的设计优美(它只是一些对象最重要的也就是对象之间的关系)而在于它体现了系统的核心价值。什么是系统的核心价值呢?我想我们的图书馆系统和华尔街的一个商
10、业系统本质的区别不在于系统用了什么语言、用了什么数据库、用的是OO还是过程,而在于系统能为使用者提供什么服务,以及提供的质量。这些通过系统的运行方式系统的运行过程系统的业务逻辑来体现。用例的价值系统分析员在接手一个系统后首先要做到的事情就是得出系统的服务和服务场景。也就是我们经常所讲的用例(use case)很多人不清楚清晰的用例的价值,只是因为看别人有漂亮的图形,所以自己也画一个,其实自己都不去看它。这样的用例分析只能糊弄一下老板,给别人show一下Demo而不会对系统开发什么实质作用。用例表示的是使用系统的一个场景其本质在于详细描述了系统用户(actor)与系统是如何交互的以及交互的后果是
11、什么详细而完善的用例将指导您进行系统开发的全过程 低耦合的设计系统对象除了与领域模型、用户打交道以外它还会与系统的其它模块交互。如持久化系统、日志系统、信息通知系统(您不能因为用户要求由邮件通知改为短信通知就修改领域模型吧),当然还有UI,这些属于系统核心(领域模型)以外的东西。这些模块不该参杂进业务逻辑中。应该在边界与这些模块进行接触。 例子:Public void 借阅()借阅处理者 处理者 = new 借阅处理者(当前书籍当前登录人姓名); Bool successful = 处理者.借阅() /這個方法主要就是上面的那2行代碼 If(successful)持久化系统.add(当前书籍)
12、;日志系统.add日志(当前当籍,”借阅”)邮件系统.发送邮件(当前书籍.当前借书人姓名) /这个例子的关键在于,你本可以在借阅()方法中先实现借阅的逻辑,然后顺势进行持久化、日志、邮件操作。可是这里却多弄了个处理者对象来专门进行借阅操作,其目的就是为了将“借阅”逻辑独立出来,与其他模块耦合更松。 例子二:Void 持久化系统.add(书籍 当前书籍)借阅关系 Bbb = new 借阅关系 Bbb.id = 产生ID() Bbb.图书ID = 当前书籍.id; Bbb.借阅人 = 当前书籍.借阅记录.借阅人姓名 Bbb.借阅时间 = 当前书籍.借阅记录.借阅时间 Bbb.Save(); 在现实
13、系统中我在if(successful)这里作了一些纯软件设计如利用C#具有Event特性将借阅方法后公开出一个事件这样我在再要添加什么外围模声时只要响应事件就可以了不需要再来动这个方法 。 其它模块处理过程类似。业务过程是系统的核心,其他模块都依赖于它而存在。一个系统要变更业务逻辑我们只要针对领域模型作变化即可再也不需要抱怨变化了OA_6_利用Rose创建各种组织机构的uml图形 OA6: 利用Rose创建各种组织机构的uml图形(.mdl)。 根据需求建立模型 职能型组织机构包括树形和直线型(集权型) 抽象出Party,可以复用一些公共的属性将树形结构关联转移到Party,可以同时支持Per
14、son和Orgnization的树形结构 混合型组织机构 矩阵型组织机构(网状组织机构)在需求分析中这几种关系最重要OA项目属于职能型 ( 一)组织机构管理l (struts) Action 与页面要注意的细节页面所需要的信息,参数,必须要在Acion里面定义好,否则页面取不出数据,Action主要负责页面数据的搜集OrgAction.javapublic class OrgAction extends ActionSupport/* * */private static final long serialVersionUID = 1L;private OrgManager orgManage
15、r;private List orgs;private int parentId;/向下导航处所有的子机构,需要传递参数,在页面上不去出来,不必注入request域public int getParentId() return parentId;public void setParentId(int parentId) this.parentId = parentId;public List getOrgs() return orgs;public void setOrgs(List orgs) this.orgs = orgs;public OrgManager getOrgManager(
16、) return orgManager;public void setOrgManager(OrgManager orgManager) this.orgManager = orgManager;public static long getSerialVersionUID() return serialVersionUID;Overridepublic String execute() throws Exception /转到索引页System.out.println(parentId);List orgs = orgManager.searchOrgs(parentId); /页面要取属性必
17、须放入request里面去ActionContext.getContext().put(orgs, orgs);return index; public String addInput()return add_input;public String add()return add_success;public String del()return del_success;要注意当查询顶级机构下的,数据存的的pid=null; 必须进行下面的控制,否则会查不出来String hql = select o from Organazation o where o.parent.id=+parentI
18、d ;if(parentId=0)hql=select o from Organazation o where o.parent.id is null ;Action里面的最核心的方法,这要一转到Action就会调用此方法,此方法里面的参数parentId也会改变public String execute() throws Exception /转到索引页System.out.println(parentId);List orgs = orgManager.searchOrgs(parentId); /页面要取属性必须放入request里面去ActionContext.getContext()
19、.put(orgs, orgs);return index;l 页面向下导航显示父机构下的所有的子机构只需要在页面要导航的地方加超链接,跟上要传的参数 a href=org.action?parentId=  ERROR LazyInitializationException 懒加载异常 出现错误的地方页面 无法显示 由于hibernate中SessionFactory是线程安全的,而其创建出来的session非线程安全 ,不能获取线程安全的懒加载类 解决办法:web.xml配置session过滤器 OpenSessionInViewFilter org.springfram
20、ework.orm.hibernate3.support.OpenSessionInViewFilter OpenSessionInViewFilter /* 注意配置的位置:配置的位置要先于Struts的filter配置文件,否则要受到struts过滤器的影响,Session的过滤器则会无效l 页面的参数以及提交问题a href=# onclick=openWin(org!addInput.action?parentId=,addOrg,600,200);在Action方法中搜集不到参数parentId,哪个方法的actiion传参数,Action中的对应的方法才能收到相应的参数,所以在开发
21、中要注意哪些参数能在方法中取得,要注意表单提交要完全成功,Action里面才能搜集到数据l 页面出现乱码的解决在web.xml配置文件中配置不管用Spring过滤器不管用 CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding GBK CharacterEncodingFilter /* 只有配置Struts的字符过滤器才管用l 分页框架需要引入分页框架当点击页面跳转的时候 ,地址栏会自动传参数http:/localhost:8080/oa_02/pagertest.jsp?
22、pager.offset=50此参数就是我们分页的步调,但是Action中要定义与之一样的接收参数的属性否则拿不到参数offsetPersonAction。Javapublic class PersonAction extends ActionSupport /* * */private static final long serialVersionUID = 1L;private PersonManager personManger;private PageModel pager;private Person person1;public Person getPerson1() return
23、 person1;public void setPerson1(Person person1) this.person1 = person1;Overridepublic String execute() throws Exception /转到索引页/List orgs = orgManager.searchOrgs(parentId);int offset = 0;if(pager!=null)offset = pager.getOffset();System.out.println(offset);pager = personManger.seachPersons(offset, 10)
24、;System.out.println(pager);ActionContext.getContext().put(pm, pager);return index; public String addInput()return add_input;public String add()return pub_add_success;public String del()return pub_del_success;public String selectFlag()return selectFlag;public PersonManager getPersonManger() return pe
25、rsonManger;public void setPersonManger(PersonManager personManger) this.personManger = personManger;public PageModel getPager() return pager;public void setPager(PageModel pager) this.pager = pager;专用的分页 Insert title here 首页 $pageNumber $pageNumber 上一页 下一页 尾页 l 在ssh框架中的易错Action的初始化,不能再application_be
26、ns.xml文件中初始化,而交给struts。Xml文件来初始化,否则出行导航收集数据是,导航的类的的属性找不到,会出target is null的不易察觉错误,所以要注意l 分页功能的抽象,使代码的重复量减少,透明度更好AbstractManager分页的逻辑图package org.passion.oa.utils;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.serv
27、let.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class PageFilter implements Filter /* * 线程变量经过过滤器过滤 */public void doFilter(ServletRequest servletRequest, Se
28、rvletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;SystemLocal.setOffset(this.getOffset(request);SystemLocal.setPagesize(this.g
29、etPagesize(request);tryfilterChain.doFilter(request, response);finally/用过一次,就是放一次资源,不释放,系统大会造成内存泄露SystemLocal.removeOffset();SystemLocal.removwPagesize(); private int getOffset(HttpServletRequest requst)/传request的目的是为了拿到页面的数据,也就是分页框架的Pager.offset的参数int offset = 0;try/如果不用filter,那页面上传来的数据必须由Action里面的
30、Pager接受,必须为Pageroffset = Integer.parseInt(requst.getParameter(pager.offset);catch(RuntimeException e)offset=0;return offset;private int getPagesize(HttpServletRequest request)return 10;public void init(FilterConfig filterConfig) throws ServletException public void destroy() _package org.passion.oa.u
31、tils;public class SystemLocal private static ThreadLocal offset = new ThreadLocal();private static ThreadLocal pagesize = new ThreadLocal();public static void setOffset(int _offset)offset.set(_offset);public static int getOffset()Integer _offset =(Integer) offset.get();if(_offset=null)return 0;retur
32、n _offset; public static void setPagesize(int _pagesize) pagesize.set(_pagesize); public static int getPagesize() Integer _pgesize = (Integer) pagesize.get(); if(_pgesize=null) return Integer.MAX_VALUE; return _pgesize; public static void removeOffset() offset.remove(); public static void removwPage
33、size() pagesize.remove(); 注意:pageFilter的配置位置,配置在前面起作用,配置在后面一般不起作用,所以对于在配置Filter的时候,一定要注意其所在的位置,以免过滤器无效l 返回 顶级机构此返回用javascript只能返回到上一级机构,而且比较麻烦,这是我们可以借助后台强大的功能,也就是拿到ppid进行再一次的查询加上这段代码if(parentId!=0)Organazation parent = orgManager.findOrg(parentId);if(parent.getParent()!=null)ppid=parent.getParent().getId();l 异常处理首先定义好一个异常类,让其继承RunnableException,让后定义好一个错页面页面如下pub_exeception.jsp出错页面 错误信息 让后在struts里面配置下面的一段 common/pub_exeception.jsp l Log4j (二)授权与认证认证授权的三元组A3BC权限控制三元组Oa项目的的类图的由来首先分析出用户 ,模块,角色三者之间的关联关系(领域模型)由于多对多关联不建议采用,要将其转换成多对一(领域模型),而产生中间类