配色: 字号:
jsp奖学金评定系统sqlserver--qk论文
2024-05-24 | 阅:  转:  |  分享 
  


基于Java的奖学金评定系统设计与实现

摘 要

本文论述了奖学金评定系统从分析到实现的整个过程,说明了系统实现的基本思路,介绍系统不同的功能模块以及实现的相关技术。学生奖学金评定管理系统是为了适应新形式下学生奖学金评定工作而准备开发的一套管理系统,其运用MySQL作为后台数据库,用Jsp、MyEclipse为开发工具。本系统能够实现学生德智体综合信息库的自动导入,按照公式自动进行德智体综合排名,根据比例要求自动生成获得奖学金学生信息、能够查询、修改各种信息,对排名、获奖学生信息进行统计,生成报表,基本满足学生、工作人员的需要;可以为教务工作有关部门提供优质、高效的业务管理和事务处理,同时采用安全可靠的处理和控制技术,及时、准确、可靠地采集和传输信息,建立完备、可靠的处理机制,提高工作效率,减少出错率。



关键词 奖学金评定系统;JSP;数据库;MySQL;MyEclipse











































THE DESIGN AND IMPLEMENTATION OF THE SCHOLARSHIP ASSESSMENT SYSTEM

Abstract

This paper discusses the scholarship assessment system the entire process from analysis to illustrate the basic idea of the system, the system function modules, as well as the related technologies. Scholarships for students assessment of management systems in order to adapt to the new form of scholarships for students under the assessment work and ready to develop a management system, the use of MySQL database as a background, with Jsp, the MyEclipse development tools. The system can automatically import comprehensive information base of students morally, intellectually, morally, intellectually and physically integrated in accordance with the formula for automatic ranking, automatically generated to get a scholarship student information to be able to query and modify all kinds of information, ranking, award-winning student information according to the ratio requirement. statistics, generate reports, and can basically meet the needs of students and staff; for the relevant departments of the administration work to provide quality and efficient business management and transaction processing, while using the secure and reliable processing and control technology, timely,accurate, reliable collection and transmission the establishment of a comprehensive,reliable information, improve efficiency, reduce the error rate。



Key words:the scholarship evaluation system;JSP;MySQL;MyEclipse

























目  录

摘要 I

Abstract II

1 引言 1

1.1 课题背景 1

1.2 研究意义 1

1.3 系统设计原理 1

1.3.1 Java简介 1

1.3.2 开发工具 2

2 需求分析 3

2.1 产品描述 3

2.2 功能列表 3

2.3 技术介绍 4

3 系统分析 5

3.1 总体设计结构图 5

3.2 功能结构设计 5

3.2.1 学生模块 5

3.2.2 辅导员模块 5

3.2.3 教务处模块 5

3.3 总用例图 6

3.4 登陆模块 7

3.5 学生模块 8

3.5.1 账号管理 9

3.5.2 申请书管理 10

3.5.3 个人信息管理 11

3.5.4 分数查询管理 12

3.6 辅导员模块 13

3.6.1 学生信息管理 14

3.6.2 申请书审核 15

3.6.3 学生帐号管理 16

3.7 教务处模块 17

3.7.1 申请书复审 18

3.7.2 信息查询 19

3.7.3 公告管理 20

4 系统设计与实现 21

4.1 模块汇总 21

4.2 数据库设计 21

4.2.1 数据库逻辑结构设计 21

4.2.2 申请信息表 22

4.2.3 奖学金管理信息表 22

4.2.4 辅表导员管理信息 22

4.2.5 声明管理信息表 23

4.2.6 成绩管理信息表 23

4.2.7 家庭情况信息表 23

4.2.8 教务处管理信息表 24

4.2.9 申请状态信息表 24

4.2.10 学生信息表 24

4.3 登录界面 25

4.4 学生界面 26

4.4.1 申请书管理界面 26

4.4.2 个人信息管理界面 28

4.4.3 家庭信息管理界面 29

4.4.4 更改密码界面 30

4.5 辅导员界面 31

4.5.1 学生成绩管理界面 31

4.6 教务处模块界面 31

4.6.1 账号管理界面 33

4.6.2 公告栏管理界面 35

5 系统调试与测试 38

5.1 程序调试 38

5.2 程序的测试 38

5.2.1 测试的重要性及目的 38

5.2.2 测试的步骤 39

5.2.3 测试的主要内容 39

结 论 41

参考文献 42

致 谢 43

外文原文 44

中文翻译 66















1 引言

1.1 课题背景

20世纪90年代以来,全球出现了一个对科技发展具有重要意义的事件:互联网应用迅速发展,网络的出现改变了世界,改变了人类的生活。Internet是世界上最大、信息资源最丰富的网络,他已经悄然地融入了我们的生活[1]。E-Mail地址、Web页地址、网上购物、网上挂号、网上拍卖、网上教学、网上股市实时行情与行情分析、评论、网上图书馆,在电视里、在报纸上已经有越来越多的人听到或看到他们的名字,越来越多的人开始了解和使用Internet。

随着技术的不断提高,计算机科学日渐成熟,使用计算机对信息资源进行管理,具有手工管理所无法比拟的优点[2],例如:检索迅速、查找方便、可靠性高、存储量大、保密性好、寿命长、成本低等。这些优点能够极大地提高信息资源管理的效率,也是科学化、正规化管理与世界接轨的重要条件。在这个背景下,教育网站的制作也随之兴起,并日渐趋于成熟起来。

1.2 研究意义

奖学金管理工作是高校学生管理工作的重要组成部分。高校为鼓励学生在校期间刻苦学习,设立了多种奖学金,同时为了做好奖学金的评审与管理工作,投入了大量的人力、物力和财力。奖学金管理工作特别是评审工作具有涉及面广、工作量大、发生时间相对集中的特点[3]。高校的奖学金评定工作每学年都要开展,传统的评审工作主要是以手工方式进行的,存在着效率低下、容易出错等弊端。因此,实现奖学金评定管理的信息化是十分必要的。

信息在社会和经济的发展中所起的作用越来越为人们所重视。信息资源的开发利用水平成为衡量一个国家综合国力的重要标志之一。计算机作为信息处理的工具,为适应信息处理需求的迅速提高,满足各类信息系统对数据库管理的需要,在文件系统的基础上发展基础数据库系统,数据库方法针对事务处理中大量数据管理需求。随着计算机管理系统的推广,数据库应用逐渐普及[4]。

目前,我国大学不断扩招,学生奖学金评定管理也日趋复杂化和多元化。为了方便奖学金的评定和管理工作,我们制作了本系统[5]。本系统采用了计算机化的评定模式,查询、修改等操作都使用了计算机的数据库技术,比起以前的手工计算方法有了很大的进步,提供了相当大的方便,而且解决了因手工操作出现的工作量大、周期长、效率低、误差、遗漏等问题,使奖学金评定管理工作变得快捷、简便、准确[6]。

1.3 技术介绍

1.3.1 Java简介

Java的特点主要表现在以下几个方面:

1.面向对象:其实是现实世界模型的自然延伸。现实世界中任何实体都可以看作是对象。对象之间通过消息相互作用。另外,现实世界中任何实体都可归属于某类事物,任何对象都是某一类事物的实例。如果说传统的过程式编程语言是以过程为中心以算法为驱动的话,面向对象的编程语言则是以对象为中心以消息为驱动[7]。用公式表示,过程式编程语言为:程序=算法+数据;面向对象编程语言为:程序=对象+消息。 所有面向对象编程语言都支持三个概念:封装、多态性和继承,Java也不例外。现实世界中的对象均有属性和行为,映射到计算机程序上,属性则表示对象的数据,行为表示对象的方法(其作用是处理数据或同外界交互)。所谓封装,就是用一个自主式框架把对象的数据和方法联在一起形成一个整体。可以说,对象是支持封装的手段,是封装的基本单位[8]。Java语言的封装性较强,因为Java无全程变量,无主函数,在Java中绝大部分成员是对象,只有简单的数字类型、字符类型和布尔类型除外。而对于这些类型,Java也提供了相应的对象类型以便与其他对象交互操作。

2.可移植性:就是在这个系统上作的程序经过一次编译后可以移植到别的系统上解释执行,只要经过简单的粘贴和复制就行了,不影响程序的效果

3.安全性:在 iSeries 服务器上运行的大多数 Java(TM) 程序是应用程序,而不是 applet,所以“砂箱”安全性模型对它们不起限制作用[9]。从安全性的观点看,Java 应用程序所受的安全性限制与 iSeries 服务器上的任何其它程序相同。要在 iSeries 服务器上运行 Java 程序,您必须对集成文件系统中的类文件具有权限。程序一旦启动,它就在该用户权限控制下运行。 您可以使用沿用权限来访问具有运行程序的用户的权限和程序拥有者权限的对象。沿用权限临时地将用户原先无权访问的对象的权限授予用户。

4.并发性:Java支持多线程技术,就是多个线程并行机制,多线程是Java的一个重要方法,特别有利于在程序中实现并发任务[10]。Java提供Thread线程类,实现了多线程的并发机制.然而,程序的并发执行必定会出现多个线程互斥访问临界资源的局面,因而并发系统解决的关键就是对临界资源的管理和分配问题,而在进行临界资源分配时有两方面需要考虑,即安全性和公平性.文中首先讨论了多线程并发系统中的安全性与公平性问题,指出安全性与公平性在并发系统中访问临界资源时的重要性.并通过火车行驶单行隧道的实例,演示各种条件下的行驶情况来进一步说明该问题。

1.3.2 开发工具

本系统开发工具是MyEclipse

1.采用MyEclipse的原因

1) MyEclipse框架的这种灵活性来源于其扩展点。它们是在XML中定义的已知接口,并充当插件的耦合点[11]。

2) 利用MyEclipse,我们可以将高级设计(也许是采用UML)与低级开发工具(如应用调试器等)结合在一起。

2.MyEclipse的特性

1)MyEclipse的最大特点是它能接受由Java开发者自己编写的开放源代码插件,这类似于微软公司的Visual Studio和Sun微系 统公司的NetBeans平台。

2)开放式可扩展的IDE。MyEclipse有极为强大的集成开发环境,它不仅集成了CVS、JUnit和Ant,并且有着绝佳的代码重构功能[12]。

3)桌面应用程序的开发平。桌面应用程序也可称为胖客端程序或GUI程序。用SWT可以像SWING一样开发独立的桌面应用,但这样无法利用MyEclipse的插件机制,所以有些人就折衷了一下:把桌面应用写成MyEclipse插件[13]。

4)全中文化的帮助文件。MyEclipse帮助的内容很全面,并且在安装好多国语言包后,MyEclipse帮助也全部中文化[14]。

2 需求分析

2.1 产品描述

高等学校学生奖学金管理是一项非常复杂的工作,但目前还没有专门的计算机软件进行统一管理。评奖学金时,我校的各系、各年级各自为政,用人工或计算机临时建库录入打印。这样不仅效率低下,而且极不规范、极不统一,造成大量的人力、物力浪费。本系统的开发实现了对学生档案管理、学生奖学金管理和毕业生成绩管理的自动化、规范化,避免了人工管理的不规范性和随意性。同时,该系统能满足用户的要求,进行可靠的录入,准确的计算和有效的查询、修改。

该系统分为4个模块,分别是登录模块、学生模块、辅导员模块、教务处模块,各模块又分为几个子功能,模块间耦合度较小。

2.2 功能列表

表2-1 系统功能列

编码 名称 简述 1 网站部分 1.1 登录功能 系统的入口,能够选择角色(学生,辅导员,教务处) 1.2 用户登录表 此功能是给要申请奖学金的学生登录的,辅导员与院校领导系统已提供各自的登录账号和密码 1.3 奖学金类型表 供学生选择要申请奖学金的类型。 1.4 学生个人信息表 学生可以查询、更新自己的基本信息,辅导员和教务处可以查询学生的基本信息 1.5 学生成绩表 供学生、教务处查询学生的成绩,辅导员可进行增、删、改、查(主:此成绩表为辅导员已录入好的表) 1.6 学生家庭情况表 供学生录入、查询、更新个人家庭情况,辅导员、教务处查询学生家庭情况 1.7 审核学生的资格 供辅导员、教务处审核学生获得奖学金的资格是否通过 2 后台部分 2.1 学生模块 学生个人信息表、学生成绩、奖惩情况表、学生家庭情况表 2.2 辅导员模块 学生个人信息表、学生成绩、奖惩情况表、学生家庭情况表、审核学生的资格,可对学生成绩表、学生奖惩情况表进行增、删、改、差,管理学生注册。 2.3 教务处模块 学生个人信息表、学生成绩、奖惩情况表、学生家庭情况表、审核学生的资格



2.3 系统质量要求

表2-2 系统质量需求

主要质量属性 详细要求 正确性 按照需求正确执行任务容错能力恢复能力软件的输出结果更新周期应该与系统的信息更新周期相同。易理解性软件研制过程中形成的所有文档语言简练、前后一致、易于理解以及语句无歧义防止软件受到意外或蓄意的存取、使用、修改、毁坏或泄密的软件属性其数据集中存放于总部的数据库服务器,客户端不保存任何业务数据和数据库连接信息,进行什么数据同步

3 系统分析

3.1 总体设计结构图











图3-1 总体设计结构图

3.2 功能结构设计

3.2.1 学生模块

学生登录后进入学生模块,学生可录入申请资料(个人信息、学生家庭情况)、可查询自己的成绩,录入和查询自己的资料信息无误后可提交。

3.2.2 辅导员模块

辅导员登录后进入辅导员模块,可对学生的成绩和奖惩进行增、删、改、查,以及审核学生的资格,辅导员确认学生的信息无误后将审核通过的学生呈报给教务处。

3.2.3 教务处模块

教务处领导登录后进入教务处模块,教务处可对注册的学生进行增、删操作、教务处领导对学生的信息查询、审核后将审核通过的学生呈报到教育局,得到教育局确认后发布获得奖学金的学生。



3.3 总用例图

如下图2所示,是奖学金评定系统的用例图。















图3-2 总用例图

3.4 登陆模块

登陆模块主要完成角色的选择和登录系统的功能,如下图3所示,是登陆模块的活动图。







图3-3 登陆模块活动图



3.5 学生模块

学生模块的功能,主要由登录和申请两部分组成,也包括信息的查看。如图3-4所示,是学生模块的活动图。





图3-4 学生模块活动图

3.5.1 账号管理

功能意义:学生更改登录密码。



图3-5 修改密码用例图



图3-6 修改密码活动图



基本信息说明

主要字段信息:账号、旧密码、新密码、确认密码。



3.5.2 申请书管理

功能意义:学生提交申请表申请奖学金

奖学金类别选择:学生选择要申请的奖学金类别

录入申请信息:录入学生个人信息、家庭情况

查询、更新申请信息:查询、更新学生个人信息、家庭情况



图3-7 申请书管理活动图

3.5.3 个人信息管理

功能意义:学生对自身信息的增删改查。



图3-8 个人信息管理用例图



图3-9 个人信息管理活动图

3.5.4 分数查询管理

学生对自己和本专业同学的分数查询。





图3-10 分数查询用例图









图3-11 分数查询活动图



3.6 辅导员模块

辅导员模块主要功能是申请书的审核管理和账号管理,其活动图如下图3-12。













图3-12 辅导员模块活动图











3.6.1 学生信息管理

功能意义:学生个人具体信息,以及账号管理。



图3-13 学生信息管理用例图







图3-14 学生信息管理活动图

3.6.2 申请书审核

功能意义:实现对学生提交申请书的管理。



图3-15 申请书审核用例图



图3-16 申请书审核活动图

3.6.3 学生帐号管理

功能意义:实现学生账号的增加,删除,修改。





图3-17 学生账号管理用例图







图3-18 学生账号管理活动图

3.7 教务处模块

教务处模块主要完成申请书复审功能、信息查询功能和公告管理功能。如图3-19,是教务处模块的活动图。











图3-19 教务处模块活动图











3.7.1 申请书复审

功能意义:实现对学生提交申请书的复审管理。



图3-20 申请书复审用例图





图3-21 申请书复审活动图

3.7.2 信息查询

功能意义:查询学生成绩、奖惩信息、个人信息

用例图



图3-22 信息查询用例图



图3-23 信息查询活动图

3.7.3 公告管理

功能意义:发布最新公告信息



图3-24 信息查询用例图





图3-25 信息查询活动图

4 系统设计与实现

4.1 模块汇总

表4-1 模块汇总

学生界面 模块名称 功能简述 申请书管理 学生录入申请奖学金的申请书管理 个人信息管理 学生对自身信息的查询管理 帐号管理(修改密码) 学生更改登录密码 公告栏 查看由教务处发布获取奖学金的学生 家庭信息管理 学生对自身家庭信息的增删改查管理 辅导员界面 模块名称 功能简述 学生信息管理模块 学生个人具体信息,以及账号管理 申请书审核管理模块 实现对学生提交申请书的管理 学生账号管理模块 实现学生账号的增加,删除,修改 账号管理 实现辅导员对自己账号的管理 教务处界面 模块名称 功能简述 申请书复审模块 实现对学生提交申请书的复审管理 信息查询模块 查询学生成绩、奖惩信息、个人信息 公告管理模块 发布最新公告信息 4.2 数据库设计

4.2.1 数据库表结构设计

表4-2 汇总表

表名 功能说明 t_ApManage 申请信息表 t_business 奖学金信息表 t_CounsellorInfo 辅导员信息表 t_Declared 公告栏信息表 t_Grade 成绩信息表 t_HomeSituation 家庭情况信息表 t_LeaderInfo 教务处信息表 t_State 申请状态信息表 t_studentinfo 学生信息表 4.2.2 申请信息表

表4-3 t_ApManage

表名 t_ApManage 列名 描述 数据类型 约束条件 SID ID int 主键 S_StClassName 名 varchar(2) years 年份 varchar(4) typeName 类型名 varchar(4) Stu_account 数量 varchar(10) stateName 状态 varchar(4) ApContent 内容 varchar(256) Cou_name 辅导员名 varchar(6) ApReCode1 编码 varchar(256) Lea_name 领导名 varchar(6) ApReCode2 编码 varchar(256) ApTitle 名字 varchar(40) 4.2.3 奖学金管理信息表

表4-4 t_business

表名 t_business 列名 描述 数据类型 约束条件 type_ID ID char(2) 主键 numbers 数量 char(4) name 名字 varchar(30) 4.2.4 辅表导员管理信息

表4-5 t_CounsellorInfo

表名 t_CounsellorInfo 列名 描述 数据类型 约束条件 SID ID int 主键 Cou_account 辅导员账号 varchar(10) Cou_password 密码 varchar(8) Cou_state 状态 char(4) Cou_role 角色 varchar(6) Cou_name 名 varchar(6) Cou_class 班级 varchar(2) 4.2.5 公告栏管理信息表

表4-6 t_Declared

表名 t_Declared 列名 描述 数据类型 约束条件 SID ID int 主键 Dec_title 文章名 varchar(30) Dec_time 时间 datetime Dec_info 信息 varchar(100) Dec_state 状态 varchar(4)

4.2.6 成绩管理信息表

表4-7 t_Grade

表名 t_Grade 列名 描述 数据类型 约束条件 SID ID int 主键 Stu_account 账户 varchar(10) stuff 材料 float credit 学分 float years 年份 varchar(2) grade 成绩 float grade_state 状态 char(4)

























4.2.7 家庭情况信息表

表4-8 t_HomeSituation

表名 t_HomeSituation 列名 描述 数据类型 约束条件 SID ID int 主键 Stu_account 帐号 varchar(10) merberName 用户名 varchar(8) homeMerL 关系 varchar(8) work 工作 varchar(20) workPlace 工作地址 varchar(50) yearEarning 年薪 varchar(50)

4.2.8 教务处管理信息表

表4-9 t_LeaderInfo

表名 t_LeaderInfo 列名 描述 数据类型 约束条件 SID ID int 主键 Lea_account 帐号 varchar(10) Lea_password 密码 varchar(10) Lea_state 状态 char(2) Lea_role 角色 varchar(6) Lea_name 名字 varchar(6)

4.2.9 申请状态信息表

表4-10 t_State

表名 t_State 列名 描述 数据类型 约束条件 SID ID int 主键 stateCode 编码 varchar(2) stateName 状态名 varchar(6) 表名 t_studentinfo 列名 描述 数据类型 约束条件 SID ID int 主键 Stu_account 帐号 varchar(10) Stu_password 密码 varchar(10) Stu_state 状态 varchar(4) Stu_role 角色 varchar(6) Stu_name 名字 varchar(6) Stu_sex 姓名 char(1) Stu_birthday 生日 nativePlace 住所 varchar(6) political 政党 varchar(6) nation 国家 varchar(6) IdCard id号 varchar(18) S_StClassName 班级名 char(20) Stu_tel 电话 varchar(11) homeAddress 地址 varchar(100)



图4-1登陆界面



相关代码:

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

String number=request.getParameter("username");

String password=request.getParameter("password");

String loginType=request.getParameter("loginType");

try{

if("1".equals(loginType)){

StudentDAO dao=new StudentDAO();

Student student= dao.StudentLogin(number, password);

if(student.getStudentAccount().equals(number)&&

student.getStudentPassword().equals(password)){

{

HttpSession session=request.getSession(false);

session=request.getSession(true);

ession.setAttribute("userID",number);

request.getRequestDispatcher("student/student_index.jsp").forward(request, response);

}

}

}catch(PasswordErrorException e){

String msg=e.getMessage();

request.setAttribute("error",msg);

request.getRequestDispatcher("loginFailed.jsp").forward(request, response);

}catch(UserNotFoundException e){

String msg=e.getMessage();

request.setAttribute("error",msg);

request.getRequestDispatcher("loginFailed.jsp").forward(request, response);

}

}



4.4 学生界面

学生用户登录成功后,会显示学生模块主页面。如图28。







图4-2 学生界面

相关代码:



















4.4.1 申请书管理界面

模块名称 申请书管理模块 功能简述 学生录入申请奖学金的申请书管理



图4-3 申请书管理模块



相关代码:

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("GB2312");

HttpSession session=request.getSession();

String account=(String) session.getAttribute("userID");

ApManageDAO ApManage=new ApManageDAO();

String title=request.getParameter("Title");

String year=(String)request.getParameter("year");

String courseCode=(String)request.getParameter("courseCode");

String scholarshipType=request.getParameter("scholarshipType");

String ApContent=request.getParameter("ApContent");

ApManage apmanage=new ApManage();

apmanage.setS_StClassName(courseCode);

apmanage.setYears(year);

apmanage.setApTitle(title);

apmanage.setTypeName(scholarshipType);

apmanage.setApContent(ApContent);

apmanage.setStateName("0102");

apmanage.setStu_account(account);

ApManage.addAplication(apmanage);

request.setAttribute("Aplist", ApManage.findAllApManagebyID(account));

request.getRequestDispatcher("../student/ApManage_show.jsp").forward(request, response);

}

4.4.2 个人信息管理界面

模块名称 个人信息管理模块 功能简述 学生对自身信息的查询管理



图4-4 个人信息模块

4.4.3 家庭信息管理界面



模块名称 家庭信息管理模块 功能简述 学生可增删改查家庭信息



图4-5 家庭信息模块



相关代码:

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("GB2312");

HomeSituationDAO Homesituationdao=new HomeSituationDAO();

HttpSession session=request.getSession();

String account=(String) session.getAttribute("userID");

String SID=session.getAttribute("SID").toString();

String merberName=request.getParameter("merberName");

String homeMerL=request.getParameter("homeMerL");

String work=request.getParameter("work");

String workPlace=request.getParameter("workPlace");

String yearEarning=request.getParameter("yearEarning");



HomeSituation homesituation=new HomeSituation();

homesituation.setStu_account(account);

homesituation.setMerberName(merberName);

homesituation.setHomeMerL(homeMerL);

homesituation.setWork(work);

homesituation.setWorkPlace(workPlace);

homesituation.setYearEarning(yearEarning);

Homesituationdao.addHomeSituation(homesituation);

request.setAttribute("HS",Homesituationdao.findHomeSituationbyID(account));

session.setAttribute("SID","");

request.getRequestDispatcher("../student/HomeSituatio_show.jsp").forward(request, response);

}



4.4.4 更改密码界面

模块名称 账号管理模块 功能简述 学生可修改密码



图4-6 密码修改模块界面

4.5 辅导员界面

在登录时,选择辅导员角色并登录,可进入辅导员管理模块。界面如图33所示



图4-7 辅导员界面

4.5.1 学生成绩管理界面

模块名称 学生成绩管理模块 功能简述 实现对学生成绩的查询

图4-8 学生成绩管理模块界面

相关代码:

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

MarkDAO markdao=new MarkDAO();

HttpSession session=request.getSession();

String account=(String) session.getAttribute("userID");

request.setAttribute("Mark",markdao.findAllGradebyaccount(account));

System.out.println(account);

request.getRequestDispatcher("../student/Mark_show.jsp").forward(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("
\"-//W3C//DTD HTML 4.01 Transitional//EN\">");

out.println("");

out.println(" ");

out.print(this.getClass());

out.println(", using the POST method");

out.println(" ");

out.println("");

out.flush();

out.close();

}

4.6 教务处模块界面

使用教务处帐号登录,可进入图35所示主界面。



图4-9 教务处界面

4.6.1 账号管理界面



模块名称 账号管理模块 功能简述 实现对学生、辅导员的账号管理

图4-10 申请书复审界面

相关代码:

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("GB2312");

LeaAccountsDAO leaAccountsDAO=new LeaAccountsDAO();

String action=request.getParameter("action");

String account=request.getParameter("account");

if(action.equals("Cupdate")){

request.setAttribute("Coustate",leaAccountsDAO.findAllstate("04"));

request.setAttribute("StuClass",leaAccountsDAO.findAllclass()); request.setAttribute("CAlist",leaAccountsDAO.findCounsellorByaccount(account)); request.getRequestDispatcher("../leader/Couaccounts_Show_go.jsp").forward(request, response);

}

if(action.equals("Cupdate1")){

String state=request.getParameter("state");

String courseCode=request.getParameter("courseCode");

leaAccountsDAO.updCouAccountstateByaccount(state,courseCode,account);

(new LeaaccountsShowServlet()).service(request, response);

}

if(action.equals("Cdelete")){

request.setAttribute("CAlist",leaAccountsDAO.findCounsellorByaccount(account) request.getRequestDispatcher("../leader/Couaccounts_Del.jsp").forward(request, response);

}

if(action.equals("Cdelete1")){

leaAccountsDAO.delCouaccount(account);

(new LeaaccountsShowServlet()).service(request, response);

}

if(action.equals("Supdate")){

request.setAttribute("Stustate",leaAccountsDAO.findAllstate("05")); request.setAttribute("SAlist",leaAccountsDAO.findStudentByaccount(account));

request.getRequestDispatcher("../leader/Stuaccounts_Show_go.jsp").forward(request, response);

}

if(action.equals("Supdate1")){

String state=request.getParameter("state");

leaAccountsDAO.updStuAccountstateByaccount(state, account);

request.setAttribute("SAlist",leaAccountsDAO.findAllStudent());

request.getRequestDispatcher("../leader/Stuaccounts_Show.jsp").forward(request, response);

}

if(action.equals("Sdelete")){

request.setAttribute("SAlist",leaAccountsDAO.findStudentByaccount(account request.getRequestDispatcher("../leader/Stuaccounts_Del.jsp").forward(request, response);

}

if(action.equals("Sdelete1")){

leaAccountsDAO.delStuaccount(account);

(new LeaaccountsShowServlet()).service(request, response);

}

if(action.equals("Cadd")){

request.setAttribute("Coustate",leaAccountsDAO.findAllstate("04"));

request.setAttribute("StuClass",leaAccountsDAO.findAllclass());

request.getRequestDispatcher("../leader/Couaccounts_Add.jsp").forward(request, response);

}

if(action.equals("Cadd1")){

String state=request.getParameter("state");

String courseCode=request.getParameter("courseCode");

leaAccountsDAO.addCouaccount(state, courseCode, account);

(new LeaaccountsShowServlet()).service(request, response);

}

if(action.equals("Sadd")){

request.setAttribute("Stustate",leaAccountsDAO.findAllstate("05"));

request.getRequestDispatcher("../leader/Stuaccounts_Add.jsp").forward(request, response);

}

if(action.equals("Sadd1")){

String state=request.getParameter("state");

leaAccountsDAO.addStudent(state, account);

(new LeaaccountsShowServlet()).service(request, response);

}

}

4.6.2 公告栏管理界面

模块名称 公告管理模块 功能简述 发布最新公告信息

图4-11 公告栏界面

相关代码:

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("GB2312");

LeaDeclaredDAO leaDeclaredDAO=new LeaDeclaredDAO();

String action=request.getParameter("action");

String SID=request.getParameter("SID");

if(action.equals("FB")){

request.setAttribute("action",action+"1");

request.setAttribute("LDelist",leaDeclaredDAO.findByID(SID));

request.getRequestDispatcher("../leader/LeaDeclared_FB.jsp").forward(request, response);}

if(action.equals("FB1")){

String state=request.getParameter("state");

leaDeclaredDAO.updDeclareBystate(SID, state);

(new LeaDeclaredShowServlet()).service(request, response);

}

if(action.equals("GX")){

String state=request.getParameter("state");

if(state.equals("0302")){

request.setAttribute("Info",new String("此公告已发布,请先将该公告取消发布!")); request.getRequestDispatcher("../leader/leawarning.jsp").forward(request, response);

}

else{

request.setAttribute("action",action+"1");

request.setAttribute("LDelist",leaDeclaredDAO.findByID(SID));

request.getRequestDispatcher("../leader/LeaDeclared_ADD.jsp").forward(request, response);

}}

if(action.equals("GX1")){

Declare declare=new Declare();

String title=request.getParameter("Title");

String apContent=request.getParameter("ApContent");

declare.setDec_title(title);

declare.setDec_info(apContent);

leaDeclaredDAO.updDeclare(SID, declare);

(new LeaDeclaredShowServlet()).service(request, response);

}

if(action.equals("SC")){

String state=request.getParameter("state");

if(state.equals("0302")){

request.setAttribute("Info",new String("此公告已发布,请先将该公告取消发布!"));

request.getRequestDispatcher("../leader/leawarning.jsp").forward(request, response);

}

else{

request.setAttribute("action",action+"1");

request.setAttribute("LDelist",leaDeclaredDAO.findByID(SID)); request.getRequestDispatcher("../leader/LeaDeclared_FB.jsp").forward(request, response);

}}

if(action.equals("SC1")){

leaDeclaredDAO.delDeclare(SID);

(new LeaDeclaredShowServlet()).service(request, response);

}

if(action.equals("ADD")){

request.setAttribute("action",action+"1");

request.setAttribute("LDelist",leaDeclaredDAO.setDeclarenull(new Declare())); request.getRequestDispatcher("../leader/LeaDeclared_ADD.jsp").forward(request, response);

}

if(action.equals("ADD1")){

Declare declare=new Declare();

String title=request.getParameter("Title");

String apContent=request.getParameter("ApContent");

String time=request.getParameter("Time");

declare.setDec_title(title);

declare.setDec_info(apContent);

declare.setDec_time(time);

leaDeclaredDAO.addDeclare(declare);

(new LeaDeclaredShowServlet()).service(request, response);}}

5.系统调试与测试

5.1 程序调试

在设计系统的过程中,存在一些错误是必然的。对于语句的语法错误,在程序运行时自动提示,并请求立即纠正,因此,这类错误比较容易发现和纠正。但另一类错误是在程序执行时由于不正确的操作或对某些数据的计算公式的逻辑错误导致的错误结果。这类错误隐蔽性强,有时会出现,有时又不出现,因此,对这一类动态发生的错误的排查是耗时费力的。

5.2 程序的测试

5.2.1 测试的重要性及目的

(1)测试的重要性

软件的测试在软件生命周期中占据重要的地位,在传统的瀑布模型中,软件测试学仅处于运行维护阶段之前,是软件产品交付用户使用之前保证软件质量的重要手段。近来,软件工程界趋向于一种新的观点,即认为软件生命周期每一阶段中都应包含测试,从而检验本阶段的成果是否接近预期的目标,尽可能早的发现错误并加以修正,如果不在早期阶段进行测试,错误的延时扩散常常会导致最后成品测试的巨大困难。

事实上,对于软件来讲,不论采用什么技术和什么方法,软件中仍然会有错。采用新的语言、先进的开发方式、完善的开发过程,可以减少错误的引入,但是不可能完全杜绝软件中的错误,这些引入的错误需要测试来找出,软件中的错误密度也需要测试来进行估计。测试是所有工程学科的基本组成单元,是软件开发的重要部分。自有程序设计的那天起测试就一直伴随着。统计表明,在典型的软件开发项目中,软件测试工作量往往占软件开发总工作量的40%以上。而在软件开发的总成本中,用在测试上的开销要占30%到50%。如果把维护阶段也考虑在内,讨论整个软件生存期时,测试的成本比例也许会有所降低,但实际上维护工作相当于二次开发,乃至多次开发,其中必定还包含有许多测试工作。

在实践中,软件测试的困难常常使人望而却步或敷衍了事,这是由于对测试仍然存在一些不正确的看法和错误的态度,这包括:

① 认为测试工作不如设计和编码那样容易取得进展难以给测试人员某种成就感;

② 以发现软件错误为目标的测试是非建设性的,甚至是破坏性的,测试中发现错位是对责任者工作的一种否定;

③ 测试工作枯燥无味,不能引起人们的兴趣;

④ 测试工作是艰苦而细致的工作;

⑤ 对自己编写的程序盲目自信,在发现错误后,顾虑别人对自己的开发能力的看法。

这些观点对软件测试工作是极为不利的,必须澄清认识、端正态度,才可能提高软件产品的质量。

(2)测试的目的

如果测试的目的是为了尽可能多地找出错误,那么测试就应该直接针对软件比较复杂的部分或是以前出错比较多的位置。

① 软件测试是为了发现错误而执行程序的过程;

② 测试是为了证明程序有错,而不是证明程序无错误;

③ 一个好的测试用例是在于它能发现至今未发现的错误;

④ 一个成功的测试是发现了至今未发现的错误的测试。

这种观点可以提醒人们测试要以查找错误为中心,而不是为了演示软件的正确功能。但是仅凭字面意思理解这一观点可能会产生误导,认为发现错误是软件测试的唯一目,查找不出错误的测试就是没有价值的,事实并非如此。

首先,测试并不仅仅是为了要找出错误。通过分析错误产生的原因和错误的分布特征,可以帮助项目管理者发现当前所采用的软件过程的缺陷,以便改进。同时,这种分析也能帮助我们设计出有针对性地检测方法,改善测试的有效性。其次,没有发现错误的测试也是有价值的,完整的测试是评定测试质量的一种方法。

5.2.2 测试的步骤

与开发过程类似,测试过程也必须分步骤进行,每个步骤在逻辑上是前一个步骤的继续。大型软件系统通常由若干个子系统组成,每个子系统又由若干个模块组成。因此,大型软件系统的测试基本上由下述几个步骤组成:

(1)模块测试 在这个测试步骤中所发现的往往是编码和详细设计的错误。

(2)系统测试 在这个测试步骤中发现的往往是软件设计中的错误,也可能发现需求说明中的错误。

(3)验收测试 在这个测试步骤中发现的往往是系统需求说明书中的错误。

5.2.3 测试的主要内容

(1)单元测试

单元测试集中在检查软件设计的最小单位—模块上,通过测试发现实现该模块的实际功能与定义该模块的功能说明不符合的情况,以及编码的错误。

(2)集成测试

集成测试是将模块按照设计要求组装起来同时进行测试,主要目标是发现与接口有关的问题。如一个模块与另一个模块可能有由于疏忽的问题而造成有害影响;把子功能组合起来可能不产生预期的主功能;个别看起来是可以接受的误差可能积累到不能接受的程度;全程数据结构可能有错误等。

(3)确认测试

确认测试的目的是向未来的用户表明系统能够像预定要求那样工作。经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是确认测试的任务,即软件的功能和性能如同用户所合理期待的那样。

(4)系统测试

软件开发完成以后,最终还要与系统中其他部分配套运行,进行系统测试。包括恢复测试、安全测试、强度测试和性能测试等。

单独对系统的测试主要从以下几方面入手:

① 功能测试:测试是否满足开发要求,是否提供设计所描述的功能,是否用户的需求都得到满足。功能测试是系统测试最常用和必须的测试,通常还会以正式的软件说明书为测试标准。

② 强度测试及性能测试:测试系统能力最高实际限度,即软件在一些超负荷情况下功能实现的情况。

③ 安全测试:验证安装在系统内的保护机构确实能够对系统进行保护,使之不受各种非常的干扰。针对本系统主要是对权限系统的测试和对无效数据、错数据、和非法数据干扰的能力的测试。

经过上述的测试过程对软件进行测试后,软件基本满足开发的要求,测试宣告结束。

结 论

在这次为期一个多月的毕业设计中,经过初期的分析、中期的开发及后期的调试,如今奖学金评定系统终于设计完毕,调试并运行通过了。在开发过程中我们本着实用、高效的原则,一切从实际情况出发。

整个过程中,从需求分析到设计、编码、测试,我们都力求规范化和文档化,努力让自己所学的知识都能运用到这次的毕业设计中,尽量保证整个系统的开发进度和质量,顺利完成这次的毕业设计。但整个过程中,我们还是遇到了不少困难,比如:在需求分析阶段中数据库的分析与设计,开发过程中数据库的连接,界面的设计等等。在此要感谢我们的指导老师,每当我们遇到困难,向老师寻求帮助时,老师都会不厌其烦地给我们讲解分析。在老师的指导下,我们不断地学习,不断地尝试,问题基本上都得到了解决。

经过一个多月的努力,我们的实践操作和动手应用能力得到了很大程度的提高。但在这个过程中,也让我们认识到我们知识面的局限性。专业知识不够全面,综合运用能力不够强,经验不足等问题。

经过这次考验,让我们认识到即使我们即将毕业,但我们的求学之路还没有结束。在以后的工作中,我们还要不断学习,不断钻研,与时俱进,学习更多的专业知识,积累更丰富的经验。才能有所成就,才不会辜负学校和老师的培育。































参考文献

1 张佳瑜闫丽媛曹敏刘琴琴陈修素高校大学生奖学金评定中的多指标模型研究[J]重庆工商大学学报(自然科学版),2010

2 贾莲芝学分制下师范院校奖学金评定系统的研究[J]河北师范大学学报(教育科学版),2009

3 朱佐想王春波学生工作信息管理系统平台的奖学金评定方法研究[J]内江科技,2007

4 李刚轻量级Java EE企业应用实战[M]第3版北京:电子工业出版社2012.

5 李刚Struts 2.x权威指南[M]第3版北京:电子工业出版社2012.

6 张海潘软件工程导论(第5版)[M]北京:清华大学出版社,2008

7 印旻,王型言JAVA语言与面向对象程序设计(第2版)[M]北京:清华大学出版社,2007

8 吕海东,张坤JAVA EE企业级应用开发实例教程[M]北京:清华大学出版社2010.

9 明日科技,卢翰,王国辉JSP项目开发案例全程实录(第2版)[M]北京清华大学出版社,2011

10 张孝祥,徐明华JSP基础与案例开发详解[M]北京:清华大学出版社,2009

11 许金梅,罗凌基于VB.NET的奖学金评定系统的研究与实现[J]重庆文理学院学报(自然科学版),2011

12 Jim Arlow. UML2.0 and the Unified Process[M].机械工业出版社,2006

13 Zoya Ali. Designing Object Oriented Software Applications within the Context of Software Frameworks[D]. Ohio State University,2011.

14 Alice Woudhuysen.China internet: The long march toward e-commerce [J].the economist intelligence unit. 2007.





























致 谢

在这次毕业设计的一个多月里,我们受到了指导老师的细心指导。老师严谨的指导态度与深厚的理论知识都让我们受益匪浅,从他身上我们学到了很多的东西,无论是理论还是实践都使我们的知识有很大的提高。当我遇到查询功能设计难题的时候,我向老师寻求帮助的时候,老师耐心详细地跟我讲解分析。

同时我们还要感谢母校的各位老师,谢谢他们三年来的悉心教导,传授给我们各种知识和做人的道理。正因有他们的教诲,我们才有能力去独立接受这次的毕业设计,并在遇到困难的时候,同心协力,共同想办法去解决困难,最终顺利完成这次毕业设计。

另外,我们还要感谢校方给予我们这样一次机会,让我们能够独立完成这个课题,并在这个过程当中给予我们各种方便使我们在即将离校的最后一段时间里,能够更多学习一些实践应用知识,增强了我们实践操作和动手应用能力,提高了独立思考的能力。再一次对我的母校表示感谢。

感谢在整个毕业设计期间,曾经在各个方面给予过我帮助的同学们,在大学生活即将结束的最后的日子里,我们再一次展现了团结合作的力量,也正是因为有了他们的帮助,才使我不仅学到了本次课题所涉及的新知识,更让我们感觉到了知识以外的东西。

最后,对于所有在这次毕业设计中给予过我们帮助的人再一次表示真诚的感谢。

























































外文原文

In web applications, most of the tasks is done in a "to prevent the user from long time waiting for the" way. In Google search this example, reduce the waiting time is essential to the user experience. A solution to the asynchronous task is to create a thread in user submission (to handle asynchronous task), but it can not solve the need to certain time interval repeat operation tasks, or at a specified time running task everyday situations.

Let us from a database of examples of statements to have a look the task scheduling can do to help improve the system design. The report may be perplexing, depending on the user for data types, and if they need from one or more database collect large amounts of data. The user may take a long time to run such an "on-demand" report. Therefore, we extend this report example add task scheduling mechanism, so that the user can be arranged in any they need time to generate a report, and in the PDF or other format in email transmission. Users can make report on every day in the morning 2:22, the system is running at low load; also can choose to only run at a specific time at a time. By the addition of task scheduling in report application, we can add a useful function for the product, and improve the user experience.

Fortunately, there is a powerful open source solutions can let us in a standard way in the application of web (or any Java application) in the implementation of task scheduling. The following example shows the application of web, how to use Quartz to create a task scheduling framework. This example also uses the Struts Action framework plug-in, so that in the web application startup initialization task scheduling mechanism. Struts is the most common MVC framework, familiar to most developers. Of course, in addition to many frameworks can help the realization of MVC model in Web application.

Startup initialization task scheduler we first need to do is create a Struts plugin, let it create task scheduler we in the container startup. In the following example, we choose Tomcat as the web application container, but these examples in other container should also can run. We want to create a Struts plug-in class, and adding a few lines of code in struts-config.xml in order to make it work. This plugin has two configurable parameters: startOnLoad specifies whether to start the task scheduler immediately in the container startup, and startupDelay specifies the waiting time before starting the task scheduler. Start delay is very useful, because we may need to perform some of the more important initialization steps. In addition, you can also use the listener mechanism, in a more complicated way to notify SchedulerPlugIn when to start Quartz Scheduler.

We want to create a Struts plug-in interface list of org.apache.struts.action.PlugIn class SchedulerPlugIn. Struts will appear in the order according to the configuration file initializes each plug-in. Special attention should be paid to the init () method in the code, we initialize the required Quartz objects, and Scheduler. The task information we will submit to a org.quartz.Scheduler object, which will be discussed in the subsequent. The Scheduler object by Quartz servlet according to its initial configuration, the ActionServlet class as the Struts initialization.

JDK provides a number of class library for programmers, and in order to keep the library reusability, scalability and flexibility, which use a lot of design patterns, this paper will introduce to use JDK I/O package in the Decorator mode, and using this model, the realization of a new output stream class.

Decorator mode Decorator mode or wrapper (Wrapper), its main purpose is to add some additional responsibilities to an object dynamically. Compared with the subclass, it has more flexibility. Sometimes, we need an object and not the whole class to add some new functions, for example, add a scrollbar functionality to a text area. We can use the inheritance mechanism to achieve this function, but this method is not flexible enough, we can not control the text area and the scroll bar mode and time. And when the text area need to add more features, such as the border, you need to create a new class, and when the combined use of these functions will undoubtedly caused an explosion required. We can use a more flexible approach, is to make text area into a scroll bar. The scrollbar class is equivalent to a decorative text area. This decoration (scroll) must and decorated component (text) inherited from the same interface, so that users don''t need to care, decoration, because it is transparent. Decoration will forward the user request to the appropriate component (that is, call the appropriate method), and may do some extra action in the forwarding and (such as add scroll). By this method, we can according to different combinations of text region nested decoration, so as to add any more function. The method of adding functions will not object this dynamic caused an explosion, also has more flexibility.

The above method is the Decorator model, which dynamically add new functionality by adding decorative objects. Component components and decorative public class, which defines the methods of subclasses must implement the. ConcreteComponent is a specific component class, you can add new features by adding decoration to it. Decorator is all the decoration of public class, which defines the method, all the decoration must achieve at the same time, it also holds a reference to Component, in order to transmit user''s request to the Component, and possibly in forwarding requests and perform some additional action. ConcreteDecoratorA and ConcreteDecoratorB are specific decoration, can use them to decorate the concrete Component.

JDK Decorator Java IO package provides the java.io package using Decorator mode to realize all kinds of input and output stream package. The following example of java.io.OutputStream and its subclasses, used to discuss the Decorator mode in IO system. The OutputStream is an abstract class, it is all the output stream public class.

It implements OutputStream in write (int b) method, so we can be used to create objects of output current, output and complete the specific format. It is equivalent to the Decorator model in the ConcreteComponent class. Similarly, it is also inherit from OutputStream. However, the constructor is very special, need to pass a OutputStream reference to it, and it will save a reference to this object. And if there is no specific OutputStream objects, we will not be able to create FilterOutputStream. Because out can be a reference to the FilterOutputStream type, can also be a reference to the ByteArrayOutputStream and other specific output stream class, so the use of multi-layer nested manner, we can add a variety of decoration for ByteArrayOutputStream. The FilterOutputStream class is equivalent to the Decorator model in the Decorator class, the write (int b) method is a simple call incoming flow write (int b) method, and not to do more, so there is no nature convection for decoration, so its subclasses must override this method, to to achieve the purpose of decoration.

BufferedOutputStream and DataOutputStream are two subclass of FilterOutputStream, which corresponds to the Decorator mode of ConcreteDecorator, and the output of the incoming flow of the different decoration. Taking BufferedOutputStream as an example:

This class provides a cache mechanism, when the cache capacity reached the number of bytes written to the output stream will only. First, it inherited FilterOutputStream, and covers the parent class write (int b) method, in the call to the output stream to write data checks the cache is full, if not full, don''t write. So as to realize the new function is added to the output stream object dynamic purpose.

Below, will use the Decorator mode, write a new output current is IO. Write a new output flow to understand the structure and principle of OutputStream and its subclasses, we can write a new output stream, to add the new function. This part will give a new output flow example, it will filter to be symbolic space output statement. Such as the need to output "Java IO OutputStream", the output is filtered for "javaioOutputStream".

In the java.io package, not only the OutputStream uses the Decorator design pattern, InputStream, Reader, Writer are used in this model. As a flexible, extensible class library, many design patterns are used in JDK, such as in the Swing package in the MVC model, RMI Proxy model etc.. Research on the JDK mode can not only deepen the understanding of the model, but also to a more thorough understanding of the structure and composition of the library.

Protocol adaptor and connector

Program MBean server depends on the protocol adaptor and connector and run the proxy Java virtual machine management for communication applications. The protocol adapter provides a registered in a management component of MBean server by specific protocol view. For example, a HTML adapter can be management component all registered displayed on a Web page. A different protocol, provides a different view. The connector must also provide management application on one side of the interface to make agent and manage application communication, namely according to different protocols, the connector must provide the remote interface similar to encapsulate the communication process. When a remote application using this interface, you can through the network transparent and agent to interact with, and ignore the protocol itself. Adaptor and connector for the MBean server and management applications can communicate. Therefore, an agent to be managed, it must provide at least one protocol adapter or connector. Facing various management application, the agent can contain a variety of different protocol adaptor and connector.

The current has been achieved and will achieve the protocol adaptor and connector includes: 1) RMI 2 SNMP protocol adapter connector) 3) IIOP protocol adapter 4) HTML protocol adapter 5) HTTP connector

Proxy service

Agent service can management component for registered to perform administrative functions. Through the introduction of intelligent management, JMX can help us build a strong management solutions. Agent service itself is a management component, can also be a MBean server control. The JMX specification defines the proxy service are:

dynamic class loading, and instantiate a new class by management program services, also can make in library local network.

monitoring service -- monitoring management component property value changes, and the notification to all listeners these changes.

3) time - time to send a message or as a scheduler using.

4) the relationship between service - definition and maintain the relationship management between components.

1 dynamic class loading dynamic class loading is obtained by m-let (management applet) services to do so, it can be seen from the network on any URL download and instantiate the management component, and then registered to the MBean server. In a M-let service process, first of all is to download a m-let file, the file is a XML file, the contents of the file identifies all information management component, such as component name, in the MBean server object that uniquely identifies the component name. Then according to the contents of this document, the m-let service to complete the remaining tasks. This process is the instantiation:

2 monitoring services through the use of monitoring service, management component property value will be regular monitoring, which is always in a specific scope. Change when monitoring the attribute value exceeded expectations defined scope, a specific notification will be issued. The current JMX specification defines three monitor:

counter monitor, monitor counter type attribute value, usually as integer, and only according to a certain law of increasing.

  2) measurement monitor, monitoring measurement type attribute value, usually for real, value can be increased or reduced.

3) string monitor, monitor the string type attribute value. Each monitor is a standard management component, the need to provide services, can be created by management component corresponding or remote management applications dynamically and configuration register.

3 time business hours service can be issued a circular in the formulation of the date and time, can also be periodic regular notice, rely on management application configuration. The time service is also a management component, it can help the management application procedures for the establishment of a configuration of the memorandum, so as to realize intelligent management service.

4 the relationship between service JMX specification defines the relationship model between the management component. A relationship is N dimensional relationship between management component user defined. Relation model is defined as follows:

the role of some terms: is is a member of a relationship between the identity, it contains a character value.

2) role information: describe a role in a relationship.

3) relationship types: composed of character information, to create and sustain a relationship as template.

4) relationship: the relationship management among members, and must meet the requirements of a relationship type.

5) role value: in a relationship in the current list management component can satisfy the given role.

6) the relationship between service: is a management component, can contact and maintain consistency between all types of relationship and relationship instances. In the relationship between services, relationship management between components by instance relationship type is determined to maintain. Only registered to the MBean server and can be the name of the object identifier management component can become a member of a relationship. The relationship between service never directly -- management component of it, in order to facilitate the search it only provides the name of the object. The relationship between service can create, locking is not reasonable relationship types similarly, creating unreasonable relations will be locked. Correction role value also should obey the consistency check. Because the relationship is defined between the management component registration contact, so when the management component which is unloaded, will change a relationship. The relationship between service will automatically change

the role value. All the relationship instance operations such as create, update, delete and so on will make the relationship between service issued a notice, notification will provide information about the operation. Only model JMX relationship to ensure management component all meet the design character of it, that is to say, does not permit a management component appears in many relationships at the same time.

Distributed service layer

At present, the SUN and there is no specific norms given this layer, only a brief description is given below.

This layer specifies the implementation of JMX application management platform interface. This layer defines the management interface and component can operate on the agent layer. These components can be:

provides an interface for managing application, so it through a connector can be transparent and agent layer or JMX management resources interact.

2) mapping through various protocols (such as SNMP, HTML etc.), provides a JMX agent and all the management component view.

3) distribution management information, in order to construct a distributed system, there will be JMX agent management information management platform to the large number of release.

4) management information collected a number of JMX proxy client and screening are of interest to the user according to the needs of management of user information and the formation of terminal users to the appropriate logical view.

5) provides security assurance.

Through the joint management application layer and a management agent and his equipment layer, can provide a complete network management solutions to our. This solution brings some advantages of the one and only for us: light, according to the needs of the deployment, dynamic services, and security.

The Java Server Pages( JSP) is a kind of according to web of the script plait distance technique, similar carries the script language of Java in the server of the Netscape company of server- side JavaScript( SSJS) and the Active Server Pages(ASP) of the Microsoft. JSP compares the SSJS and ASP to have better can expand sex, and it is no more exclusive than any factory or some one particular server of Web. Though the norm of JSP is to be draw up by the Sun company of, any factory can carry out the JSP on own system.

If Java is, in fact, yet another computer programming language, you may question why it is so important and why it is being promoted as a revolutionary step in computer programming. The answer isn’t immediately obvious if you’re coming from a traditional programming perspective. Although Java is very useful for solving traditional stand-alone programming problems, it is also important because it will solve programming problems on the World Wide Web.

The Web’s initial server-browser design provided for interactive content, but the interactivity was completely provided by the server. The server produced static pages for the client browser, which would simply interpret and display them. Basic HTML contains simple mechanisms for data gathering: text-entry boxes, check boxes, radio boxes, lists and drop-down lists, as well as a button that can only be programmed to reset the data on the form or “submit” the data on the form back to the server.

This submission passes through the Common Gateway Interface (CGI) provided on all Web servers. The text within the submission tells CGI what to do with it. The most common action is to run a program located on the server in a directory that’s typically called “cgi-bin.” (If you watch the address window at the top of your browser when you push a button on a Web page, you can sometimes see “cgi-bin” within all the gobbledygook there.) These programs can be written in most languages. Perl is a common choice because it is designed for text manipulation and is interpreted, so it can be installed on any server regardless of processor or operating system. Many powerful Web sites today are built strictly on CGI, and you can in fact do nearly anything with it. However, Web sites built on CGI programs can rapidly become overly complicated to maintain, and there is also the problem of response time. The response of a CGI program depends on how much data must be sent, as well as the load on both the server and the Internet. (On top of this, starting a CGI program tends to be slow.)

The initial designers of the Web did not foresee how rapidly this bandwidth would be exhausted for the kinds of applications people developed. For example, any sort of dynamic graphing is nearly impossible to perform with consistency because a GIF file must be created and moved from the server to the client for each version of the graph. And you’ve no doubt had direct experience with something as simple as validating the data on an input form. You press the submit button on a page; the data is shipped back to the server; the server starts a CGI program that discovers an error, formats an HTML page informing you of the error, and then sends the page back to you; you must then back up a page and try again. Not only is this slow, it’s inelegant.

The solution is client-side programming. Most machines that run Web browsers are powerful engines capable of doing vast work, and with the original static HTML approach they are sitting there, just idly waiting for the server to dish up the next page. Client-side programming means that the Web browser is harnessed to do whatever work it can, and the result for the user is a much speedier and more interactive experience at your Web site. The problem with discussions of client-side programming is that they aren’t very different from discussions of programming in general. The parameters are almost the same, but the platform is different: a Web browser is like a limited operating system. In the end, you must still program, and this accounts for the dizzying array of problems and solutions produced by client-side programming. The rest of this section provides an overview of the issues and approaches in client-side programming.

One of the most significant steps forward in client-side programming is the development of the plug-in. This is a way for a programmer to add new functionality to the browser by downloading a piece of code that plugs itself into the appropriate spot in the browser. It tells the browser “from now on you can perform this new activity.” (You need to download the plug-in only once.) Some fast and powerful behavior is added to browsers via plug-ins, but writing a plug-in is not a trivial task, and isn’t something you’d want to do as part of the process of building a particular site. The value of the plug-in for client-side programming is that it allows an expert programmer to develop a new language and add that language to a browser without the permission of the browser manufacturer. Thus, plug-ins provide a “back door” that allows the creation of new client-side programming languages (although not all languages are implemented as plug-ins).

Plug-ins resulted in an explosion of scripting languages. With a scripting language you embed the source code for your client-side program directly into the HTML page, and the plug-in that interprets that language is automatically activated while the HTML page is being displayed. Scripting languages tend to be reasonably easy to understand and, because they are simply text that is part of an HTML page, they load very quickly as part of the single server hit required to procure that page. The trade-off is that your code is exposed for everyone to see (and steal).

Generally, however, you aren’t doing amazingly sophisticated things with scripting languages so this is not too much of a hardship. This points out that the scripting languages used inside Web browsers are really intended to solve specific types of problems, primarily the creation of richer and more interactive graphical user interfaces (GUIs). However, a scripting language might solve 80 percent of the problems encountered in client-side programming.

Your problems might very well fit completely within that 80 percent, and since scripting languages can allow easier and faster development, you should probably consider a scripting language before looking at a more involved solution such as Java or ActiveX programming. The most commonly discussed browser scripting languages are JavaScript (which has nothing to do with Java; it’s named that way just to grab some of Java’s marketing momentum), VBScript (which looks like Visual Basic), and Tcl/Tk, which comes from the popular cross-platform GUI-building language. There are others out there, and no doubt more in development.

JavaScript is probably the most commonly supported. It comes built into both Netscape Navigator and the Microsoft Internet Explorer (IE). In addition, there are probably more JavaScript books available than there are for the other browser languages, and some tools automatically create pages using JavaScript. However, if you’re already fluent in Visual Basic or Tcl/Tk, you’ll be more productive using those scripting languages rather than learning a new one. (You’ll have your hands full dealing with the Web issues already.

If a scripting language can solve 80 percent of the client-side programming problems, what about the other 20 percent—the “really hard stuff?” The most popular solution today is Java. Not only is it a powerful programming language built to be secure, cross-platform, and international, but Java is being continually extended to provide language features and libraries that elegantly handle problems that are difficult in traditional programming languages, such as multithreading, database access, network programming, and distributed computing. Java allows client-side programming via the applet.

An applet is a mini-program that will run only under a Web browser. The applet is downloaded automatically as part of a Web page (just as, for example, a graphic is automatically downloaded). When the applet is activated it executes a program. This is part of its beauty—it provides you with a way to automatically distribute the client software from the server at the time the user needs the client software, and no sooner. The user gets the latest version of the client software without fail and without difficult reinstallation. Because of the way Java is designed, the programmer needs to create only a single program, and that program automatically works with all computers that have browsers with built-in Java interpreters. (This safely includes the vast majority of machines.) Since Java is a full-fledged programming language, you can do as much work as possible on the client before and after making requests of the server. For example, you won’t need to send a request form across the Internet to discover that you’ve gotten a date or some other parameter wrong, and your client computer can quickly do the work of plotting data instead of waiting for the server to make a plot and ship a graphic image back to you. Not only do you get the immediate win of speed and responsiveness, but the general network traffic and load on servers can be reduced, preventing the entire Internet from slowing down. One advantage a Java applet has over a scripted program is that it’s in compiled form, so the source code isn’t available to the client. On the other hand, a Java applet can be decompiled without too much trouble, but hiding your code is often not an important issue. Two other factors can be important. As you will see later in this book, a compiled Java applet can comprise many modules and take multiple server “hits” (accesses) to download. (In Java 1.1 and higher this is minimized by Java archives, called JAR files, that allow all the required modules to be packaged together and compressed for a single download.)

A scripted program will just be integrated into the Web page as part of its text (and will generally be smaller and reduce server hits). This could be important to the responsiveness of your Web site. Another factor is the all-important learning curve. Regardless of what you’ve heard, Java is not a trivial language to learn. If you’re a Visual Basic programmer, moving to VBScript will be your fastest solution, and since it will probably solve most typical client/server problems you might be hard pressed to justify learning Java. If you’re experienced with a scripting language you will certainly benefit from looking at JavaScript or VBScript before committing to Java, since they might fit your needs handily and you’ll be more productive sooner.to run its applets withi

To some degree, the competitor to Java is Microsoft’s ActiveX, although it takes a completely different approach. ActiveX was originally a Windows-only solution, although it is now being developed via an independent consortium to become cross-platform. Effectively, ActiveX says “if your program connects to its environment just so, it can be dropped into a Web page and run under a browser that supports ActiveX.” (IE directly supports ActiveX and Netscape does so using a plug-in.) Thus, ActiveX does not constrain you to a particular language. If, for example, you’re already an experienced Windows programmer using a language such as C++, Visual Basic, or Borland’s Delphi, you can create ActiveX components with almost no changes to your programming knowledge. ActiveX also provides a path for the use of legacy code in your Web pages.

Automatically downloading and running programs across the Internet can sound like a virus-builder’s dream. ActiveX especially brings up the thorny issue of security in client-side programming. If you click on a Web site, you might automatically download any number of things along with the HTML page: GIF files, script code, compiled Java code, and ActiveX components. Some of these are benign; GIF files can’t do any harm, and scripting languages are generally limited in what they can do. Java was also designed to run its applets within a “sandbox” of safety, which prevents it from writing to disk or accessing memory outside the sandbox.

ActiveX is at the opposite end of the spectrum. Programming with ActiveX is like programming Windows—you can do anything you want. So if you click on a page that downloads an ActiveX component, that component might cause damage to the files on your disk. Of course, programs that you load onto your computer that are not restricted to running inside a Web browser can do the same thing. Viruses downloaded from Bulletin-Board Systems (BBSs) have long been a problem, but the speed of the Internet amplifies the difficulty.

The solution seems to be “digital signatures,” whereby code is verified to show who the author is. This is based on the idea that a virus works because its creator can be anonymous, so if you remove the anonymity individuals will be forced to be responsible for their actions. This seems like a good plan because it allows programs to be much more functional, and I suspect it will eliminate malicious mischief. If, however, a program has an unintentional destructive bug it will still cause problems.

The Java approach is to prevent these problems from occurring, via the sandbox. The Java interpreter that lives on your local Web browser examines the applet for any untoward instructions as the applet is being loaded. In particular, the applet cannot write files to disk or erase files (one of the mainstays of viruses). Applets are generally considered to be safe, and since this is essential for reliable client/server systems, any bugs in the Java language that allow viruses are rapidly repaired. (It’s worth noting that the browser software actually enforces these security restrictions, and some browsers allow you to select different security levels to provide varying degrees of access to your system.) You might be skeptical of this rather draconian restriction against writing files to your local disk. For example, you may want to build a local database or save data for later use offline. The initial vision seemed to be that eventually everyone would get online to do anything important, but that was soon seen to be impractical (although low-cost “Internet appliances” might someday satisfy the needs of a significant segment of users). The solution is the “signed applet” that uses public-key encryption to verify that an applet does indeed come from where it claims it does. A signed applet can still trash your disk, but the theory is that since you can now hold the applet creator accountable they won’t do vicious things. Java provides a framework for digital signatures so that you will eventually be able to allow an applet to step outside the sandbox if necessary. Digital signatures have missed an important issue, which is the speed that people move around on the Internet. If you download a buggy program and it does something untoward, how long will it be before you discover the damage? It could be days or even weeks. By then, how will you track down the program that’s done it? And what good will it do you at that point?

The Web is the most general solution to the client/server problem, so it makes sense that you can use the same technology to solve a subset of the problem, in particular the classic client/server problem within a company. With traditional client/server approaches you have the problem of multiple types of client computers, as well as the difficulty of installing new client software, both of which are handily solved with Web browsers and client-side programming. When Web technology is used for an information network that is restricted to a particular company, it is referred to as an intranet. Intranets provide much greater security than the Internet, since you can physically control access to the servers within your company. In terms of training, it seems that once people understand the general concept of a browser it’s much easier for them to deal with differences in the way pages and applets look, so the learning curve for new kinds of systems seems to be reduced.

The security problem brings us to one of the divisions that seems to be automatically forming in the world of client-side programming. If your program is running on the Internet, you don’t know what platform it will be working under, and you want to be extra careful that you don’t disseminate buggy code. You need something cross-platform and secure, like a scripting language or Java.

If you’re running on an intranet, you might have a different set of constraints. It’s not uncommon that your machines could all be Intel/Windows platforms. On an intranet, you’re responsible for the quality of your own code and can repair bugs when they’re discovered. In addition, you might already have a body of legacy code that you’ve been using in a more traditional client/server approach, whereby you must physically install client programs every time you do an upgrade. The time wasted in installing upgrades is the most compelling reason to move to browsers, because upgrades are invisible and automatic. If you are involved in such an intranet, the most sensible approach to take is the shortest path that allows you to use your existing code base, rather than trying to recode your programs in a new language.

When faced with this bewildering array of solutions to the client-side programming problem, the best plan of attack is a cost-benefit analysis. Consider the constraints of your problem and what would be the shortest path to your solution. Since client-side programming is still programming, it’s always a good idea to take the fastest development approach for your particular situation. This is an aggressive stance to prepare for inevitable encounters with the problems of program development.

This whole discussion has ignored the issue of server-side programming. What happens when you make a request of a server? Most of the time the request is simply “send me this file.” Your browser then interprets the file in some appropriate fashion: as an HTML page, a graphic image, a Java applet, a script program, etc. A more complicated request to a server generally involves a database transaction. A common scenario involves a request for a complex database search, which the server then formats into an HTML page and sends to you as the result. (Of course, if the client has more intelligence via Java or a scripting language, the raw data can be sent and formatted at the client end, which will be faster and less load on the server.) Or you might want to register your name in a database when you join a group or place an order, which will involve changes to that database. These database requests must be processed via some code on the server side, which is generally referred to as server-side programming. Traditionally, server-side programming has been performed using Perl and CGI scripts, but more sophisticated systems have been appearing. These include Java-based Web servers that allow you to perform all your server-side programming in Java by writing what are called servlets. Servlets and their offspring, JSPs, are two of the most compelling reasons that companies who develop Web sites are moving to Java, especially because they eliminate the problems of dealing with differently abled browsers.

Much of the brouhaha over Java has been over applets. Java is actually a general-purpose programming language that can solve any type of problem—at least in theory. And as pointed out previously, there might be more effective ways to solve most client/server problems. When you move out of the applet arena (and simultaneously release the restrictions, such as the one against writing to disk) you enter the world of general-purpose applications that run standalone, without a Web browser, just like any ordinary program does. Here, Java’s strength is not only in its portability, but also its programmability. As you’ll see throughout this book, Java has many features that allow you to create robust programs in a shorter period than with previous programming languages. Be aware that this is a mixed blessing. You pay for the improvements through slower execution speed (although there is significant work going on in this area—JDK 1.3, in particular, introduces the so-called “hotspot” performance improvements). Like any language, Java has built-in limitations that might make it inappropriate to solve certain types of programming problems. Java is a rapidly evolving language, however, and as each new release comes out it becomes more and more attractive for solving larger sets of problems.

All programming languages provide abstractions. It can be argued that the complexity of the problems you’re able to solve is directly related to the kind and quality of abstraction. By “kind” I mean, “What is it that you are abstracting?” Assembly language is a small abstraction of the underlying machine. Many so-called “imperative” languages that followed (such as FORTRAN, BASIC, and C) were abstractions of assembly language. These languages are big improvements over assembly language, but their primary abstraction still requires you to think in terms of the structure of the computer rather than the structure of the problem you are trying to solve. The programmer must establish the association between the machine model (in the “solution space,” which is the place where you’re modeling that problem, such as a computer) and the model of the problem that is actually being solved (in the “problem space,” which is the place where the problem exists). The effort required to perform this mapping, and the fact that it is extrinsic to the programming language, produces programs that are difficult to write and expensive to maintain, and as a side effect created the entire “programming methods” industry.

The alternative to modeling the machine is to model the problem you’re trying to solve. Early languages such as LISP and APL chose particular views of the world (“All problems are ultimately lists” or “All problems are algorithmic,” respectively). PROLOG casts all problems into chains of decisions. Languages have been created for constraint-based programming and for programming exclusively by manipulating graphical symbols. (The latter proved to be too restrictive.) Each of these approaches is a good solution to the particular class of problem they’re designed to solve, but when you step outside of that domain they become awkward.

The object-oriented approach goes a step further by providing tools for the programmer to represent elements in the problem space. This representation is general enough that the programmer is not constrained to any particular type of problem. We refer to the elements in the problem space and their representations in the solution space as “objects.” (You will also need other objects that don’t have problem-space analogs.) The idea is that the program is allowed to adapt itself to the lingo of the problem by adding new types of objects, so when you read the code describing the solution, you’re reading words that also express the problem. This is a more flexible and powerful language abstraction than what we’ve had before. Thus, OOP allows you to describe the problem in terms of the problem, rather than in terms of the computer where the solution will run. There’s still a connection back to the computer: each object looks quite a bit like a little computer—it has a state, and it has operations that you can ask it to perform. However, this doesn’t seem like such a bad analogy to objects in the real world—they all have characteristics and behaviors.

Alan Kay summarized five basic characteristics of Smalltalk, the first successful object-oriented language and one of the languages upon which Java is based. These characteristics represent a pure approach to object-oriented programming:

Everything is an object. Think of an object as a fancy variable; it stores data, but you can “make requests” to that object, asking it to perform operations on itself. In theory, you can take any conceptual component in the problem you’re trying to solve (dogs, buildings, services, etc.) and represent it as an object in your program.

A program is a bunch of objects telling each other what to do by sending messages. To make a request of an object, you “send a message” to that object. More concretely, you can think of a message as a request to call a method that belongs to a particular object.

Each object has its own memory made up of other objects. Put another way, you create a new kind of object by making a package containing existing objects. Thus, you can build complexity into a program while hiding it behind the simplicity of objects.

Every object has a type. Using the parlance, each object is an instance of a class, in which “class” is synonymous with “type.” The most important distinguishing characteristic of a class is “What messages can you send to it?”

All objects of a particular type can receive the same messages. This is actually a loaded statement, as you will see later. Because an object of type “circle” is also an object of type “shape,” a circle is guaranteed to accept shape messages. This means you can write code that talks to shapes and automatically handle anything that fits the description of a shape. This substitutability is one of the powerful concepts in OOP.

Booch offers an even more succinct description of an object:

An object has state, behavior and identity. This means that an object can have internal data (which gives it state), methods (to produce behavior), and each object can be uniquely distinguished from every other object—to put this in a concrete sense, each object has a unique address in memory.

Aristotle was probably the first to begin a careful study of the concept of type; he spoke of “the class of fishes and the class of birds.” The idea that all objects, while being unique, are also part of a class of objects that have characteristics and behaviors in common was used directly in the first object-oriented language, Simula-67, with its fundamental keyword class that introduces a new type into a program.

Simula, as its name implies, was created for developing simulations such as the classic “bank teller problem.” In this, you have a bunch of tellers, customers, accounts, transactions, and units of money—a lot of “objects.” Objects that are identical except for their state during a program’s execution are grouped together into “classes of objects” and that’s where the keyword class came from. Creating abstract data types (classes) is a fundamental concept in object-oriented programming. Abstract data types work almost exactly like built-in types: You can create variables of a type (called objects or instances in object-oriented parlance) and manipulate those variables (called sending messages or requests; you send a message and the object figures out what to do with it). The members (elements) of each class share some commonality: every account has a balance, every teller can accept a deposit, etc. At the same time, each member has its own state: each account has a different balance, each teller has a name. Thus, the tellers, customers, accounts, transactions, etc., can each be represented with a unique entity in the computer program. This entity is the object, and each object belongs to a particular class that defines its characteristics and behaviors.

So, although what we really do in object-oriented programming is create new data types, virtually all object-oriented programming languages use the “class” keyword. When you see the word “type” think “class” and vice versa. Since a class describes a set of objects that have identical characteristics (data elements) and behaviors (functionality), a class is really a data type because a floating point number, for example, also has a set of characteristics and behaviors. The difference is that a programmer defines a class to fit a problem rather than being forced to use an existing data type that was designed to represent a unit of storage in a machine. You extend the programming language by adding new data types specific to your needs. The programming system welcomes the new classes and gives them all the care and type-checking that it gives to built-in types.

The object-oriented approach is not limited to building simulations. Whether or not you agree that any program is a simulation of the system you’re designing, the use of OOP techniques can easily reduce a large set of problems to a simple solution. Once a class is established, you can make as many objects of that class as you like, and then manipulate those objects as if they are the elements that exist in the problem you are trying to solve. Indeed, one of the challenges of object-oriented programming is to create a one-to-one mapping between the elements in the problem space and objects in the solution space.

But how do you get an object to do useful work for you? There must be a way to make a request of the object so that it will do something, such as complete a transaction, draw something on the screen, or turn on a switch. And each object can satisfy only certain requests. The requests you can make of an object are defined by its interface, and the type is what determines the interface.

The interface establishes what requests you can make for a particular object. However, there must be code somewhere to satisfy that request. This, along with the hidden data, comprises the implementation. From a procedural programming standpoint, it’s not that complicated. A type has a method associated with each possible request, and when you make a particular request to an object, that method is called. This process is usually summarized by saying that you “send a message” (make a request) to an object, and the object figures out what to do with that message (it executes code).

Here, the name of the type/class is Light, the name of this particular Light object is lt, and the requests that you can make of a Light object are to turn it on, turn it off, make it brighter, or make it dimmer. You create a Light object by defining a “reference” (lt) for that object and calling new to request a new object of that type. To send a message to the object, you state the name of the object and connect it to the message request with a period (dot). From the standpoint of the user of a predefined class, that’s pretty much all there is to programming with objects.

The preceding diagram follows the format of the Unified Modeling Language (UML). Each class is represented by a box, with the type name in the top portion of the box, any data members that you care to describe in the middle portion of the box, and the methods (the functions that belong to this object, which receive any messages you send to that object) in the bottom portion of the box. Often, only the name of the class and the public methods are shown in UML design diagrams, so the middle portion is not shown. If you’re interested only in the class name, then the bottom portion doesn’t need to be shown, either 1.3 An object provides services.

While you’re trying to develop or understand a program design, one of the best ways to think about objects is as “service providers.” Your program itself will provide services to the user, and it will accomplish this by using the services offered by other objects. Your goal is to produce (or even better, locate in existing code libraries) a set of objects that provide the ideal services to solve your problem.

A way to start doing this is to ask “if I could magically pull them out of a hat, what objects would solve my problem right away?” For example, suppose you are creating a bookkeeping program. You might imagine some objects that contain pre-defined bookkeeping input screens, another set of objects that perform bookkeeping calculations, and an object that handles printing of checks and invoices on all different kinds of printers. Maybe some of these objects already exist, and for the ones that don’t, what would they look like? What services would those objects provide, and what objects would they need to fulfill their obligations? If you keep doing this, you will eventually reach a point where you can say either “that object seems simple enough to sit down and write” or “I’m sure that object must exist already.” This is a reasonable way to decompose a problem into a set of objects.

Thinking of an object as a service provider has an additional benefit: it helps to improve the cohesiveness of the object. High cohesion is a fundamental quality of software design: It means that the various aspects of a software component (such as an object, although this could also apply to a method or a library of objects) “fit together” well. One problem people have when designing objects is cramming too much functionality into one object. For example, in your check printing module, you may decide you need an object that knows all about formatting and printing. You’ll probably discover that this is too much for one object, and that what you need is three or more objects. One object might be a catalog of all the possible check layouts, which can be queried for information about how to print a check. One object or set of objects could be a generic printing interface that knows all about different kinds of printers (but nothing about bookkeeping—this one is a candidate for buying rather than writing yourself). And a third object could use the services of the other two to accomplish the task. Thus, each object has a cohesive set of services it offers. In a good object-oriented design, each object does one thing well, but doesn’t try to do too much. As seen here, this not only allows the discovery of objects that might be purchased (the printer interface object), but it also produces the possibility of an object that might be reused somewhere else (the catalog of check layouts).

Treating objects as service providers is a great simplifying tool, and it’s very useful not only during the design process, but also when someone else is trying to understand your code or reuse an object—if they can see the value of the object based on what service it provides, it makes it much easier to fit it into the design.









































中文翻译

在web应用中,大多数任务是以一种"防止用户长时间等待"的方式完成的。在Google搜索这样的例子中,减少等待时间对用户体验来说至关重要。异步任务的一种解决方案是在用户提交后生成一个线程(来处理异步任务),但这也不能解决那些需以一定时间间隔重复运行任务、或在每天的指定时间运行任务的情况。   让我们从一个数据库报表的例子来看看任务调度能如何帮助改善系统设计。报表可能是错综复杂的,这取决于用户所需数据的种类,以及是否需要从一个或多个数据库收集大量数据。用户可能需要很长时间来运行这样的"按需"报表。因此,我们向这个报表示例中添加任务调度机制,以便用户可以安排在任何他们需要的时间生成报表,并以PDF或其他格式在email中发送。用户可以让报表在每天的凌晨2:22,系统正处于低负荷时运行;也可以选择只在特定时间运行一次。通过在报表应用中加入任务调度,我们可以为产品添加一项有用的功能,并改善用户体验。   幸运的是,有一个强大的开源解决方案可以让我们以标准的方式在web应用(或任何Java应用)中实施任务调度。以下示例展示了在web应用中,如何使用Quartz来创建一个任务调度框架。这个示例还使用了Struts Action framework 插件,以便在web应用启动时初始化任务调度机制。Struts是最常见的MVC框架,为大多数开发人员所熟悉。当然除此之外还有许多框架可以协助在web应用中实现MVC模式。   启动时初始化任务调度器   我们首先要做的是建立一个Struts插件,让它在容器启动时创建我们的任务调度器。在以下例子中,我们选择Tomcat作为web应用容器,不过这些示例在其他容器中也应当可以运行。我们要创建一个Struts插件类,并在struts-config.xml中加入几行代码以使之可以工作。   这个插件有两个可配置的初始化参数:startOnLoad指定是否要在容器启动时立即启动任务调度器,而 startupDelay指定启动任务调度器之前的等待时间。启动延时很有用,因为我们可能需要首先执行一些更重要的初始化步骤。此外还可以使用listener机制,以更复杂的方式来通知SchedulerPlugIn何时启动Quartz Scheduler。   我们要创建的是一个实现Struts插件接口org.apache.struts.action.PlugIn的单子类SchedulerPlugIn。Struts会按照配置文件中出现的顺序初始化各个插件。要特别注意的是init()方法中的代码,在此我们初始化了所需的Quartz对象,并得到Scheduler。我们的任务信息就要提交到此org.quartz.Scheduler对象,后者将在随后讨论。Scheduler对象由Quartz servlet根据其配置初始化,就像Struts初始化它的ActionServlet类一样。

JDK为程序员提供了大量的类库,而为了保持类库的可重用性,可扩展性和灵活性,其中使用到了大量的设计模式,本文将介绍JDK的I/O包中使用到的Decorator模式,并运用此模式,实现一个新的输出流类。   Decorator模式简介   Decorator模式又名包装器(Wrapper),它的主要用途在于给一个对象动态的添加一些额外的职责。与生成子类相比,它更具有灵活性。 有时候,我们需要为一个对象而不是整个类添加一些新的功能,比如,给一个文本区添加一个滚动条的功能。我们可以使用继承机制来实现这一功能,但是这种方法不够灵活,我们无法控制文本区加滚动条的方式和时机。而且当文本区需要添加更多的功能时,比如边框等,需要创建新的类,而当需要组合使用这些功能时无疑将会引起类的爆炸。   我们可以使用一种更为灵活的方法,就是把文本区嵌入到滚动条中。而这个滚动条的类就相当于对文本区的一个装饰。这个装饰(滚动条)必须与被装饰的组件(文本区)继承自同一个接口,这样,用户就不必关心装饰的实现,因为这对他们来说是透明的。装饰会将用户的请求转发给相应的组件(即调用相关的方法),并可能在转发的前后做一些额外的动作(如添加滚动条)。通过这种方法,我们可以根据组合对文本区嵌套不同的装饰,从而添加任意多的功能。这种动态的对对象添加功能的方法不会引起类的爆炸,也具有了更多的灵活性。   以上的方法就是Decorator模式,它通过给对象添加装饰来动态的添加新的功能。Component为组件和装饰的公共父类,它定义了子类必须实现的方法。   ConcreteComponent是一个具体的组件类,可以通过给它添加装饰来增加新的功能。   Decorator是所有装饰的公共父类,它定义了所有装饰必须实现的方法,同时,它还保存了一个对于Component的引用,以便将用户的请求转发给Component,并可能在转发请求前后执行一些附加的动作。   ConcreteDecoratorA和ConcreteDecoratorB是具体的装饰,可以使用它们来装饰具体的Component。   Java IO包中的Decorator模式   JDK提供的java.io包中使用了Decorator模式来实现对各种输入输出流的封装。以下将以java.io.OutputStream及其子类为例,讨论一下Decorator模式在IO中的使用。   OutputStream是一个抽象类,它是所有输出流的公共父类。   它实现了OutputStream中的write(int b)方法,因此我们可以用来创建输出流的对象,并完成特定格式的输出。它相当于Decorator模式中的ConcreteComponent类。 同样,它也是从OutputStream继承。但是,它的构造函数很特别,需要传递一个OutputStream的引用给它,并且它将保存对此对象的引用。而如果没有具体的OutputStream对象存在,我们将无法创建FilterOutputStream。由于out既可以是指向FilterOutputStream类型的引用,也可以是指向ByteArrayOutputStream等具体输出流类的引用,因此使用多层嵌套的方式,我们可以为ByteArrayOutputStream添加多种装饰。这个FilterOutputStream类相当于Decorator模式中的Decorator类,它的write(int b)方法只是简单的调用了传入的流的write(int b)方法,而没有做更多的处理,因此它本质上没有对流进行装饰,所以继承它的子类必须覆盖此方法,以达到装饰的目的。   BufferedOutputStream 和 DataOutputStream是FilterOutputStream的两个子类,它们相当于Decorator模式中的ConcreteDecorator,并对传入的输出流做了不同的装饰。以BufferedOutputStream类为例:   这个类提供了一个缓存机制,等到缓存的容量达到一定的字节数时才写入输出流。首先它继承了FilterOutputStream,并且覆盖了父类的write(int b)方法,在调用输出流写出数据前都会检查缓存是否已满,如果未满,则不写。这样就实现了对输出流对象动态的添加新功能的目的。   下面,将使用Decorator模式,为IO写一个新的输出流。   自己写一个新的输出流   了解了OutputStream及其子类的结构原理后,我们可以写一个新的输出流,来添加新的功能。这部分中将给出一个新的输出流的例子,它将过滤待输出语句中的空格符号。比如需要输出"java io OutputStream",则过滤后的输出为"javaioOutputStream"。   在java.io包中,不仅OutputStream用到了Decorator设计模式,InputStream,Reader,Writer等都用到了此模式。而作为一个灵活的,可扩展的类库,JDK中使用了大量的设计模式,比如在Swing包中的MVC模式,RMI中的Proxy模式等等。对于JDK中模式的研究不仅能加深对于模式的理解,而且还有利于更透彻的了解类库的结构和组成。

协议适配器和连接器

MBean服务器依赖于协议适配器和连接器来和运行该代理的Java虚拟机之外的管理应用程序进行通信。协议适配器通过特定的协议提供了一张注册在MBean服务器的管理构件的视图。例如,一个HTML适配器可以将所有注册过的管理构件显示在Web 页面上。不同的协议,提供不同的视图。   连接器还必须提供管理应用一方的接口以使代理和管理应用程序进行通信,即针对不同的协议,连接器必须提供同样的远程接口来封装通信过程。当远程应用程序使用这个接口时,就可以通过网络透明的和代理进行交互,而忽略协议本身。   适配器和连接器使MBean服务器与管理应用程序能进行通信。因此,一个代理要被管理,它必须提供至少一个协议适配器或者连接器。面临多种管理应用时,代理可以包含各种不同的协议适配器和连接器。 当前已经实现和将要实现的协议适配器和连接器包括:   1)RMI连接器   2)SNMP协议适配器   3)IIOP协议适配器   4)HTML协议适配器   5)HTTP连接器

代理服务

  代理服务可以对注册的管理构件执行管理功能。通过引入智能管理,JMX可以帮助我们建立强有力的管理解决方案。代理服务本身也是作为管理构件而存在,也可以被MBean服务器控制。 JMX规范定义了代理服务有:   1)动态类装载--通过管理小程序服务可以获得并实例化新的类,还可以使位于网络上的类库本地化。   2)监视服务--监视管理构件的属性值变化,并将这些变化通知给所有的监听者。   3)时间服务--定时发送一个消息或作为一个调度器使用。   4)关系服务--定义并维持管理构件之间的相互关系。 1.动态类装载   动态类装载是通过m-let(management applet)服务来实现的,它可以从网络上的任何URL处下载并实例化管理构件,然后向MBean服务器注册。在一个M-let服务过程中,首先是下载一个m-let文本文件,该文件是XML格式的文件,文件的内容标识了管理构件的所有信息,比如构件名称、在MBean服务器中唯一标识该构件的对象名等。然后根据这个文件的内容,m-let服务完成剩余的任务。下图例示这一过程: 2.监视服务   通过使用监视服务,管理构件的属性值就会被定期监视,从而保证始终处于一个特定的范围。当监视的属性值的变化超出了预期定义的范围,一个特定的通告就会发出。JMX规范当前规定了三种监视器:   1)计数器监视器,监视计数器类型的属性值,通常为整型,且只能按一定规律递增。   2)度量监视器,监视度量类型的属性值,通常为实数,值能增能减。   3)字符串监视器,监视字符串类型的属性值。   每一个监视器都是作为一个标准管理构件存在的,需要提供服务时,可以由相应的管理构件或远程管理应用程序动态创建并配置注册使用。 3.时间服务   时间服务可以在制定的时间和日期发出通告,也可以定期的周期性的发出通告,依赖于管理应用程序的配置。时间服务也是一个管理构件,它能帮助管理应用程序建立一个可配置的备忘录,从而实现智能管理服务。 4.关系服务   JMX规范定义了管理构件之间的关系模型。一个关系是用户定义的管理构件之间的N维联系。 关系模型定义如下一些术语:   1)角色:就是是一个关系中的一类成员身份,它含有一个角色值。   2)角色信息:描述一个关系中的一个角色。   3)关系类型:由角色信息组成,作为创建和维持关系的模板。   4)关系:管理构件之间的当前联系,且必须满足一个关系类型的要求。   5)角色值:在一个关系中当前能满足给定角色的管理构件的列表。   6)关系服务:是一个管理构件,能接触和维持所有关系类型和关系实例之间的一致性。   在关系服务中,管理构件之间的关系由通过关系类型确定的关系实例来维护。仅仅只有注册到MBean服务器上并且能被对象名标识的管理构件才能成为一个关系的成员。关系服务从来就不直接操作它的成员--管理构件,为了方便查找它仅仅提供了对象名。   关系服务能锁定不合理关系类型的创建,同样,不合理的关系的创建也会被锁定。角色值的修正也要遵守一致性检查。   由于关系是定义在注册的管理构件之间的联系,所以当其中的管理构件卸载时,就会更改关系。关系服务会自动更改角色值。所有对关系实例的操作比如创建、更新、删除等都会使关系服务发出通告,通告会提供有关这次操作的信息。   JMX关系模型只能保证所有的管理构件满足它的设计角色,也就是说,不允许一个管理构件同时出现在许多关系中。

分布服务层

  当前,SUN并没有给出这一层的具体规范,下面给出的只是一个简要描述。   该层规定了实现JMX应用管理平台的接口。这一层定义了能对代理层进行操作的管理接口和组件。这些组件能:   1)为管理应用程序提供一个接口,以便它通过一个连接器能透明和代理层或者JMX管理资源进行交互。   2)通过各种协议的映射(如SNMP、HTML等),提供了一个JMX代理和所有可管理组件的视图。   3)分布管理信息,以便构造一个分布式系统,也就是将高层管理平台的管理信息向其下众多的JMX代理发布。   4)收集多个JMX 代理端的管理信息并根据管理终端用户的需要筛选用户感兴趣的信息并形成逻辑视图送给相应的终端用户。   5)提供了安全保证。   通过管理应用层和另一管理代理和以及他的设备层的联合,就可以为我们提供一个完整的网络管理的解决方案。这个解决方案为我们带来了独一无二的一些优点:轻便、根据需要部署、动态服务、还有安全性。

Java服务器页面(JSP )是一种根据脚本编程技术,进行类似的Java在Netscape公司的服务器端JavaScript ( SSJS )和活动服务器页面( ASP的服务器脚本语言的网站微软的)。JSP的比较SSJS和ASP有更好的可扩展性,它并不比任何工厂或网站的某一个特定的服务器更加独特。虽然JSP的规范是由SUN公司来制定,任何工厂可以进行JSP上自己的系统。

既然Java不过另一种类型的程序设计语言,大家可能会奇怪它为什么值得如此重视,为什么还有这么多的人认为它是计算机程序设计的一个里程碑呢?如果您来自一个传统的程序设计背景,那么答案在刚开始的时候并不是很明显。Java除了可解决传统的程序设计问题以外,还能解决World Wide Web(万维网)上的编程问题。

Web最初采用的“服务器-浏览器”方案可提供交互式内容,但这种交互能力完全由服务器提供,为服务器和因特网带来了不小的负担。服务器一般为客户浏览器产生静态网页,由后者简单地解释并显示出来。基本HTML语言提供了简单的数据收集机制:文字输入框、复选框、单选钮、列表以及下拉列表等,另外还有一个按钮,只能由程序规定重新设置表单中的数据,以便回传给服务器。用户提交的信息通过所有Web服务器均能支持的“通用网关接口”(CGI)回传到服务器。包含在提交数据中的文字指示CGI该如何操作。最常见的行动是运行位于服务器的一个程序。那个程序一般保存在一个名为“cgi-bin”的目录中(按下Web页内的一个按钮时,请注意一下浏览器顶部的地址窗,经常都能发现“cgi-bin”的字样)。大多数语言都可用来编制这些程序,但其中最常见的是Perl。这是由于Perl是专为文字的处理及解释而设计的,所以能在任何服务器上安装和使用,无论采用的处理器或操作系统是什么。

朝客户端编程迈进的时候,最重要的一个问题就是插件的设计。利用插件,程序员可以方便地为浏览器添加新功能,用户只需下载一些代码,把它们“插入”浏览器的适当位置即可。这些代码的作用是告诉浏览器“从现在开始,你可以进行这些新活动了”(仅需下载这些插入一次)。有些快速和功能强大的行为是通过插件添加到浏览器的。但插件的编写并不是一件简单的任务。在我们构建一个特定的站点时,可能并不希望涉及这方面的工作。对客户端程序设计来说,插件的价值在于它允许专业程序员设计出一种新的语言,并将那种语言添加到浏览器,同时不必经过浏览器原创者的许可。由此可以看出,插件实际是浏览器的一个“后门”,允许创建新的客户端程序设计语言(尽管并非所有语言都是作为插件实现的。

插件造成了脚本编制语言的爆炸性增长。通过这种脚本语言,可将用于自己客户端程序的源码直接插入HTML页,而对那种语言进行解释的插件会在HTML页显示的时候自动激活。脚本语言一般都倾向于尽量简化,易于理解。而且由于它们是从属于HTML页的一些简单正文,所以只需向服务器发出对那个页的一次请求,即可非常快地载入。缺点是我们的代码全部暴露在人们面前。另一方面,由于通常不用脚本编制语言做过分复杂的事情,所以这个问题暂且可以放在一边。 脚本语言真正面向的是特定类型问题的解决,其中主要涉及如何创建更丰富、更具有互动能力的图形用户界面(GUI)。然而,脚本语言也许能解决客户端编程中80%的问题。你碰到的问题可能完全就在那80%里面。而且由于脚本编制语言的宗旨是尽可能地简化与快速,所以在考虑其他更复杂的方案之前(如Java及ActiveX),首先应想一下脚本语言是否可行。

目前讨论得最多的脚本编制语言包括JavaScript(它与Java没有任何关系;之所以叫那个名字,完全是一种市场策略)、VBScript(同Visual Basic很相似)以及Tcl/Tk(来源于流行的跨平台GUI构造语言)。当然还有其他许多语言,也有许多正在开发中。 JavaScript也许是日常用的,它得到的支持也最全面。无论NetscapeNavigator,Microsoft Internet Explorer,还是Opera,目前都提供了对JavaScript的支持。除此以外,市面上讲述JavaScript的书籍也要比讲述其他语言的书多得多。有些工具还能利用JavaScript自动产生网页。当然,如果你已经有Visual Basic或者Tcl/Tk的深厚功底,当然用它们要简单得多,起码可以避免学习新语言的烦恼(解决Web方面的问题就已经够让人头痛了)。

如果说一种脚本编制语言能解决80%的客户端程序设计问题,那么剩下的20%又该怎么办呢?它们属于一些高难度的问题吗?目前最流行的方案就是Java。它不仅是一种功能强大、高度安全、可以跨平台使用以及国际通用的程序设计语言,也是一种具有旺盛生命力的语言。对Java的扩展是不断进行的,提供的语言特性和库能够很好地解决传统语言不能解决的问题,比如多线程操作、数据库访问、连网程序设计以及分布式计算等等。Java通过“程序片”(Applet)巧妙地解决了客户端编程的问题。

程序片(或“小应用程序”)是一种非常小的程序,只能在Web浏览器中运行。作为Web页的一部分,程序片代码会自动下载回来(这和网页中的图片差不多)。激活程序片后,它会执行一个程序。程序片的一个优点体现在:通过程序片,一旦用户需要客户软件,软件就可从服务器自动下载回来。它们能自动取得客户软件的最新版本,不会出错,也没有重新安装的麻烦。由于Java的设计原理,程序员只需要创建程序的一个版本,那个程序能在几乎所有计算机以及安装了Java解释器的浏览器中运行。由于Java是一种全功能的编程语言,所以在向服务器发出一个请求之前,我们能先在客户端做完尽可能多的工作。例如,再也不必通过因特网传送一个请求表单,再由服务器确定其中是否存在一个拼写或者其他参数错误。大多数数据校验工作均可在客户端完成,没有必要坐在计算机前面焦急地等待服务器的响应。这样一来,不仅速度和响应的灵敏度得到了极大的提高,对网络和服务器造成的负担也可以明显减轻,这对保障因特网的畅通是至关重要的。

与脚本程序相比,Java程序片的另一个优点是它采用编译好的形式,所以客户端看不到源码。当然在另一方面,反编译Java程序片也并不是件难事,而且代码的隐藏一般并不是个重要的问题。大家要注意另外两个重要的问题。正如本书以前会讲到的那样,编译好的Java程序片可能包含了许多模块,所以要多次“命中”(访问)服务器以便下载(在Java 1.1中,这个问题得到了有效的改善——利用Java压缩档,即JAR文件——它允许设计者将所有必要的模块都封装到一起,供用户统一下载)。在另一方面,脚本程序是作为Web页正文的一部分集成到Web页内的。这种程序一般都非常小,可有效减少对服务器的点击数。另一个因素是学习方面的问题。不管你平时听别人怎么说,Java都不是一种十分容易便可学会的语言。如果你以前是一名Visual Basic程序员,那么转向VBScript会是一种最快捷的方案。由于VBScript可以解决大多数典型的客户机/服务器问题,所以一旦上手,就很难下定决心再去学习Java。如果对脚本编制语言比较熟,那么在转向Java之前,建议先熟悉一下JavaScript或者VBScript,因为它们可能已经能够满足你的需要,不必经历学习Java的艰苦过程。

在某种程度上,Java的一个有力竞争对手应该是微软的ActiveX,尽管它采用的是完全不同的一套实现机制。ActiveX最早是一种纯Windows的方案。经过一家独立的专业协会的努力,ActiveX现在已具备了跨平台使用的能力。实际上,ActiveX的意思是“假如你的程序同它的工作环境正常连接,它就能进入Web页,并在支持ActiveX的浏览器中运行”(IE固化了对ActiveX的支持,而Netscape需要一个插件)。所以,ActiveX并没有限制我们使用一种特定的语言。比如,假设我们已经是一名有经验的Windows程序员,能熟练地使用像C++、Visual Basic或者Borland Delphi那样的语言,就能几乎不加任何学习地创建出ActiveX组件。事实上,ActiveX是在我们的Web页中使用“历史遗留”代码的最佳途径。

自动下载和通过因特网运行程序听起来就像是一个病毒制造者的梦想。在客户端的编程中,ActiveX带来了最让人头痛的安全问题。点击一个Web站点的时候,可能会随同HTML网页传回任何数量的东西:GIF文件、脚本代码、编译好的Java代码以及ActiveX组件。有些是无害的;GIF文件不会对我们造成任何危害,而脚本编制语言通常在自己可做的事情上有着很大的限制。Java也设计成在一个安全“沙箱”里在它的程序片中运行,这样可防止操作位于沙箱以外的磁盘或者内存区域。

ActiveX是所有这些里面最让人担心的。用ActiveX编写程序就像编制Windows应用程序——可以做自己想做的任何事情。下载回一个ActiveX组件后,它完全可能对我们磁盘上的文件造成破坏。当然,对那些下载回来并不限于在Web浏览器内部运行的程序,它们同样也可能破坏我们的系统。从BBS下载回来的病毒一直是个大问题,但因特网的速度使得这个问题变得更加复杂。

目前解决的办法是“数字签名”,代码会得到权威机构的验证,显示出它的作者是谁。这一机制的基础是认为病毒之所以会传播,是由于它的编制者匿名的缘故。所以假如去掉了匿名的因素,所有设计者都不得不为它们的行为负责。这似乎是一个很好的主意,因为它使程序显得更加正规。但我对它能消除恶意因素持怀疑态度,因为假如一个程序便含有Bug,那么同样会造成问题。

Java通过“沙箱”来防止这些问题的发生。Java解释器内嵌于我们本地的Web浏览器中,在程序片装载时会检查所有有嫌疑的指令。特别地,程序片根本没有权力将文件写进磁盘,或者删除文件(这是病毒最喜欢做的事情之一)。我们通常认为程序片是安全的。而且由于安全对于营建一套可靠的客户机/服务器系统至关重要,所以会给病毒留下漏洞的所有错误都能很快得到修复(浏览器软件实际需要强行遵守这些安全规则;而有些浏览器则允许我们选择不同的安全级别,防止对系统不同程度的访问)。

大家或许会怀疑这种限制是否会妨碍我们将文件写到本地磁盘。比如,我们有时需要构建一个本地数据库,或将数据保存下来,以便日后离线使用。最早的版本似乎每个人都能在线做任何敏感的事情,但这很快就变得非常不现实(尽管低价“互联网工具”有一天可能会满足大多数用户的需要)。解决的方案是“签了名的程序片”,它用公共密钥加密算法验证程序片确实来自它所声称的地方。当然在通过验证后,签了名的一个程序片仍然可以开始清除你的磁盘。但从理论上说,既然现在能够找到创建人“算帐”,他们一般不会干这种蠢事。Java 1.1为数字签名提供了一个框架,在必要时,可让一个程序片“走”到沙箱的外面来。

数字签名遗漏了一个重要的问题,那就是人们在因特网上移动的速度。如下载回一个错误百出的程序,而它很不幸地真的干了某些蠢事,需要多久的时间才能发觉这一点呢?这也许是几天,也可能几周之后。发现了之后,又如何追踪当初肇事的程序呢(以及它当时的责任有多大)?

Web是解决客户机/服务器问题的一种常用方案,所以最好能用相同的技术解决此类问题的一些“子集”,特别是公司内部的传统客户机/服务器问题。对于传统的客户机/服务器模式,我们面临的问题是拥有多种不同类型的客户计算机,而且很难安装新的客户软件。但通过Web浏览器和客户端编程,这两类问题都可得到很好的解决。若一个信息网络局限于一家特定的公司,那么在将Web技术应用于它之后,即可称其为“内联网”(Intranet),以示与国际性的“因特网”(Internet)有别。内联网提供了比因特网更高的安全级别,因为可以物理性地控制对公司内部服务器的使用。说到培训,一般只要人们理解了浏览器的常规概念,就可以非常轻松地掌握网页和程序片之间的差异,所以学习新型系统的开销会大幅度减少。

安全问题将我们引入客户端编程领域一个似乎是自动形成的分支。若程序是在因特网上运行,由于无从知晓它会在什么平台上运行,所以编程时要特别留意,防范可能出现的编程错误。需作一些跨平台处理,以及适当的安全防范,比如采用某种脚本语言或者Java。

但假如在内联网中运行,面临的一些制约因素就会发生变化。全部机器均为Intel/Windows平台是件很平常的事情。在内联网中,需要对自己代码的质量负责。而且一旦发现错误,就可以马上改正。除此以外,可能已经有了一些“历史遗留”的代码,并用较传统的客户机/服务器方式使用那些代码。但在进行升级时,每次都要物理性地安装一道客户程序。浪费在升级安装上的时间是转移到浏览器的一项重要原因。使用了浏览器后,升级就变得易如反掌,而且整个过程是透明和自动进行的。如果真的是牵涉到这样的一个内联网中,最明智的方法是采用ActiveX,而非试图采用一种新的语言来改写程序代码。

面临客户端编程问题令人困惑的一系列解决方案时,最好的方案是先做一次投资/回报分析。请总结出问题的全部制约因素,以及什么才是最快的方案。由于客户端程序设计仍然要编程,所以无论如何都该针对自己的特定情况采取最好的开发途径。这是准备面对程序开发中一些不可避免的问题时,我们可以做出的最佳姿态。

我们的整个讨论都忽略了服务器端编程的问题。如果向服务器发出一个请求,会发生什么事情?大多数时候的请求都是很简单的一个“把这个文件发给我”。浏览器随后会按适当的形式解释这个文件:作为HTML页、一幅图、一个Java程序片、一个脚本程序等等。向服务器发出的较复杂的请求通常涉及到对一个数据库进行操作(事务处理)。其中最常见的就是发出一个数据库检索命令,得到结果后,服务器会把它格式化成HTML页,并作为结果传回来(当然,假如客户通过Java或者某种脚本语言具有了更高的智能,那么原始数据就能在客户端发送和格式化;这样做速度可以更快,也能减轻服务器的负担)。另外,有时需要在数据库中注册自己的名字(比如加入一个组时),或者向服务器发出一份订单,这就涉及到对那个数据库的修改。这类服务器请求必须通过服务器端的一些代码进行,我们称其为“服务器端的编程”。在传统意义上,服务器端编程是用Perl和CGI脚本进行的,但更复杂的系统已经出现。其中包括基于Java的Web服务器,它允许我们用Java进行所有服务器端编程,写出的程序就叫做“小服务程序”(Servlet)。

与Java有关的大多数争论都是与程序片有关的。Java实际是一种常规用途的程序设计语言,可解决任何类型的问题,至少理论上如此。而且正如前面指出的,可以用更有效的方式来解决大多数客户机/服务器问题。如果将视线从程序片身上转开(同时放宽一些限制,比如禁止写盘等),就进入了常规用途的应用程序的广阔领域。这种应用程序可独立运行,毋需浏览器,就象普通的执行程序那样。在这儿,Java的特色并不仅仅反应在它的移植能力,也反映在编程本身上。就像贯穿全书都会讲到的那样,Java提供了许多有用的特性,使我们能在较短的时间里创建出比用从前的程序设计语言更健壮的程序。 但要注意任何东西都不是十全十美的,我们为此也要付出一些代价。其中最明显的是执行速度放慢了(尽管可对此进行多方面的调整)。和任何语言一样,Java本身也存在一些限制,使得它不十分适合解决某些特殊的编程问题。但不管怎样,Java都是一种正在快速发展的语言。随着每个新版本的发布,它变得越来越可爱,能充分解决的问题也变得越来越多。

所有编程语言的最终目的都是提供一种“抽象”方法。一种较有争议的说法是:解决问题的复杂 程度直接取决于抽象的种类及质量。这儿的“种类”是指准备对什么进行“抽象”?汇编语言是对基础机器的少量抽象。后来的许多“命令式”语言(如FORTRAN,BASIC和C)是对汇编语言的一种抽象。与汇编语言相比,这些语言已有了长足的进步,但它们的抽象原理依然要求我们着重考虑计算机的结构,而非考虑问题本身的结构。在机器模型(位于“方案空间”)与实际解决的问题模型(位于“问题空间”)之间,程序员必须建立起一种联系。这个过程要求人们付出较大的精力,而且由于它脱离了编程语言本身的范围,造成程序代码很难编写,而且要花较大的代价进行维护。由此造成的副作用便是一门完善的“编程方法”学科。

为机器建模的另一个方法是为要解决的问题制作模型。对一些早期语言来说,如LISP和APL,它们的做法是“从不同的角度观察世界”——“所有问题都归纳为列表”或“所有问题都归纳为算法”。PROLOG则将所有问题都归纳为决策链。对于这些语言,我们认为它们一部分是面向基于“强制”的编程,另一部分则是专为处理图形符号设计的。每种方法都有自己特殊的用途,适合解决某一类的问题。但只要超出了它们力所能及的范围,就会显得非常笨拙。

面向对象的程序设计在此基础上则跨出了一大步,程序员可利用一些工具表达问题空间内的元素。由于这种表达非常普遍,所以不必受限于特定类型的问题。我们将问题空间中的元素以及它们在方案空间的表示物称作“对象”(Object)。当然,还有一些在问题空间没有对应体的其他对象。通过添加新的对象类型,程序可进行灵活的调整,以便与特定的问题配合。所以在阅读方案的描述代码时,会读到对问题进行表达的话语。与我们以前见过的相比,这无疑是一种更加灵活、更加强大的语言抽象方法。总之,OOP允许我们根据问题来描述问题,而不是根据方案。然而,仍有一个联系途径回到计算机。每个对象都类似一台小计算机;它们有自己的状态,而且可要求它们进行特定的操作。与现实世界的“对象”或者“物体”相比,编程“对象”与它们也存在共通的地方:它们都有自己的特征和行为。 Alan Kay总结了Smalltalk的五大基本特征。这是第一种成功的面向对象程序设计语言,也是Java的基础语言。通过这些特征,我们可理解“纯粹”的面向对象程序设计方法是什么样的。

所有东西都是对象。可将对象想象成一种新型变量;它保存着数据,但可要求它对自身进行操作。理论上讲,可从要解决的问题身上提出所有概念性的组件,然后在程序中将其表达为一个对象。

程序是一大堆对象的组合;通过消息传递,各对象知道自己该做些什么。为了向对象发出请求,需向那个对象“发送一条消息”。更具体地讲,可将消息想象为一个调用请求,它调用的是从属于目标对象的一个子例程或函数。

每个对象都有自己的存储空间,可容纳其他对象。或者说,通过封装现有对象,可制作出新型对象。所以,尽管对象的概念非常简单,但在程序中却可达到任意高的复杂程度。

每个对象都有一种类型。根据语法,每个对象都是某个“类”的一个“实例”。其中,“类”(Class)是“类型”(Type)的同义词。一个类最重要的特征就是“能将什么消息发给它?”。

同一类所有对象都能接收相同的消息。这实际是别有含义的一种说法,大家不久便能理解。由于类型为“圆”(Circle)的一个对象也属于类型为“形状”(Shape)的一个对象,所以一个圆完全能接收形状消息。这意味着可让程序代码统一指挥“形状”,令其自动控制所有符合“形状”描述的对象,其中自然包括“圆”。这一特性称为对象的“可替换性”,是OOP最重要的概念之一。 一些语言设计者认为面向对象的程序设计本身并不足以方便解决所有形式的程序问题,提倡将不同的方法组合成“多形程序设计语言”。

亚里士多德或许是认真研究“类型”概念的第一人,他曾谈及“鱼类和鸟类”的问题。在世界首例面向对象语言Simula-67中,第一次用到了这样的一个概念: 所有对象——尽管各有特色——都属于某一系列对象的一部分,这些对象具有通用的特征和行为。在Simula-67中,首次用到了class这个关键字,它为程序引入了一个全新的类型(clas和type通常可互换使用;注释③)。③:有些人进行了进一步的区分,他们强调“类型”决定了接口,而“类”是那个接口的一种特殊实现方式。

Simula是一个很好的例子。正如这个名字所暗示的,它的作用是“模拟”(Simulate)象“银行出纳员”这样的经典问题。在这个例子里,我们有一系列出纳员、客户、帐号以及交易等。每类成员(元素)都具有一些通用的特征:每个帐号都有一定的余额;每名出纳都能接收客户的存款;等等。与此同时,每个成员都有自己的状态;每个帐号都有不同的余额;每名出纳都有一个名字。所以在计算机程序中,能用独一无二的实体分别表示出纳员、客户、帐号以及交易。这个实体便是“对象”,而且每个对象都隶属一个特定的“类”,那个类具有自己的通用特征与行为。 因此,在面向对象的程序设计中,尽管我们真正要做的是新建各种各样的数据“类型”(Type),但几乎所有面向对象的程序设计语言都采用了“class”关键字。当您看到“type”这个字的时候,请同时想到“class”;反之亦然。

建好一个类后,可根据情况生成许多对象。随后,可将那些对象作为要解决问题中存在的元素进行处理。事实上,当我们进行面向对象的程序设计时,面临的最大一项挑战性就是:如何在“问题空间”(问题实际存在的地方)的元素与“方案空间”(对实际问题进行建模的地方,如计算机)的元素之间建立理想的“一对一”对应或映射关系。

如何利用对象完成真正有用的工作呢?必须有一种办法能向对象发出请求,令其做一些实际的事情,比如完成一次交易、在屏幕上画一些东西或者打开一个开关等等。每个对象仅能接受特定的请求。我们向对象发出的请求是通过它的“接口”(Interface)定义的,对象的“类型”或“类”则规定了它的接口形式。“类型”与“接口”的等价或对应关系是面向对象程序设计的基础。

在这个例子中,类型/类的名称是Light,可向Light对象发出的请求包括包括打开(on)、关闭(off)、变得更明亮(brighten)或者变得更暗淡(dim)。通过简单地声明一个名字(lt),我们为Light对象创建了一个“句柄”。然后用new关键字新建类型为Light的一个对象。再用等号将其赋给句柄。为了向对象发送一条消息,我们列出句柄名(lt),再用一个句点符号(.)把它同消息名称(on)连接起来。从中可以看出,使用一些预先定义好的类时,我们在程序里采用的代码是非常简单和直观的。

当你开发一个程序或者分析一个程序设计时,理解对象的最佳的方式是把他们当作“服务提供者”。程序本身会为用户提供服务,而它通过使用其它对象所提供的服务来完成这个工作。你的任务是制作(或者在更理想的情况下,从现有的代码库中找出)一组能为解决问题提供最佳服务的对象。

这么做的第一步是问“如果我可以像变魔术那样把东西从帽子里拿出来,我该拿出些什么东西,哪些对象能立即帮我解决问题?”举例来说,假设你要创建一个簿记程序。可能你会想应该有一些保存预设的输入界面的对象,一组进行簿记计算的对象,以及一个能在各种打印机上打印支票和发票的对象。

有些对象或许已经有了,但是那些还没有的应该是什么样的呢?它们应该提供哪种服务,还有它们要完成任务的话,又该用哪些对象呢?如果你不断分析下去,最终你会发现,不是“那个对象写起来很容易”就是“那个对象已经有了。”这是将问题分解成一组对象的一个合理的方法。

将对象视作为服务的提供者还有一个额外的优点:能提高对象的内聚星。内聚性高是高质量的软件设计一个基本要求:就是说软件的各种组将应该能很好的“组装在一起” 设计对象时常犯的一个错误就是,往对象里塞了太多的功能。举例来说,设计支票打印模块的时候,你也许会决定设计一个能通晓所有排格式和打印工作细节的对象。很快你就会发现这个任务太艰巨了,或许应该用三个或是更多对象来完成这个工作。第一个对象应该是支票格式的目录册,通过查询这个目录册可以获取得该如何打印支票的信息。第二个对象,或是一组对象,应该是能分辨各种打印机的通用的打印接口。以及使用上述两个对象所提供的服务的,能最终完成任务的第三个对象。由此每个对象都提供一组互补的功能。在一个良好的面向对象的设计中,每个对象都应该只做一件事,并且做好一件事,而不是去做太多的事情。就像这里看到的,这样不仅能发现那些对象因该买(打印机接口对象),而且能设计出今后能复用的对象(支票格式的目录册)。

将对象视作服务的提供者还是一种很了不起的简化工具。它不仅在设计过程中有用,而且还能帮助别人理解你的代码或者复用这个对象—如果它们认同这个对象所提供的服务的话。将对象视作服务的提供者能使对象更容易被用于设计









































IV



66







献花(0)
+1
(本文系zy_360tsg原创)