首页 java毕业设计--用Java web开发的网上商城系统

java毕业设计--用Java web开发的网上商城系统

举报
开通vip

java毕业设计--用Java web开发的网上商城系统哈尔滨理工大学 题 目: 网上商城系统 院、 系: 计算机科学与技术学院 网络工程系 姓 名: 指导教师: 系主任: 2010年06月25日 哈尔滨理工大学学士学位论文 网上商城系统 摘 要 目前,人们的购物方式已经变得多种多样,在现实中的商场、超市、各种店铺,还有就是在网上购物。网络购物作为一种新的购物形式被广大群众所接受,尤其是年轻群体。 因此本文的主要研究对象就是网上商城系统,研究网上商城一般的业务流程,还有网上商城的结构和模块,各个模块的功能等等。整个论文从如何来分析一个网上商城系统的业务流...

java毕业设计--用Java web开发的网上商城系统
哈尔滨理工大学 题 目: 网上商城系统 院、 系: 计算机科学与技术学院 网络工程系 姓 名: 指导教师: 系主任: 2010年06月25日 哈尔滨理工大学学士学位论文 网上商城系统 摘 要 目前,人们的购物方式已经变得多种多样,在现实中的商场、超市、各种店铺,还有就是在网上购物。网络购物作为一种新的购物形式被广大群众所接受,尤其是年轻群体。 因此本文的主要研究对象就是网上商城系统,研究网上商城一般的业务 流程 快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计 ,还有网上商城的结构和模块,各个模块的功能等等。整个论文从如何来 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 一个网上商城系统的业务流程和它的结构以及模块,再到到对开发工具的选择,以及对前面分析出来的结果进行初步的设计(这里我设计的是使用Java的web开发技术来实现这个网上商城系统),对网上商城系统分析和设计完成之后,就进入到实际的代码编写阶段,在这个阶段就可能对前面的设计进行一定的修改或是完善。在开发阶段,我将采用的是螺旋递增式的开发,每次只完成一部分功能,然后就立即对这些功能进行测试,接着进入下一个开发阶段,然后继续测试,直到所有的功能全部实现后,再对整个系统进行一个完整的测试,看其是否达到了先前的设计要求。 综上所述,本文讨论的就是如何使用Java的web开发技术来完整的实现一个网上商城系统的主要功能。 关键词 网上商城;Java;Web开发 I- 哈尔滨理工大学学士学位论文 Online Shopping Mall System Abstract At present, people's shopping patterns have become diverse, in reality shopping malls, supermarkets, various shops, and the online shopping. Online shopping as a new form of shopping has been accepted by the masses, especially in younger age groups. So in this paper we will discuss the Online Shopping Mall, study the general business processes of online shopping mall, and the Online Shopping Mall's structure and modules, the functions of each module, and so on. This paper start from how to analysis a Online Shopping Mall’s business process and it’s structure, then we go to choose development tools, next I will make a preliminary design (here I designed to use the java web technology to achieve this Online Shopping Mall), all this done, then we go to type the code, in development stage I use the Increasing spiral development model, it just completed a part of the function, then I will test this part, then a other part, step by step, until all the Online Shopping Mall be complete, after this I will do a complete test for the whole system, to check if it meets the design requirements previously. So in this paper, we discuss how to use java web technology to build a Online Shopping Mall. Keywords Online Shopping Mall; Java; Web Development II- 哈尔滨理工大学学士学位论文 目 录 摘要…… .......................................................................................................... I Abstract .......................................................................................................... II 第1章 绪论 ................................................................................................... 1 1.1 选题目的和意义 .................................................................................. 1 1.2 论文研究内容 ...................................................................................... 1 1.3 什么是网上商城 .................................................................................. 2 1.4 网上商城的分类 .................................................................................. 3 第2章 网上商城系统的需求分析 ............................................................... 4 2.1 网上商城业务流程分析 ...................................................................... 4 2.1.1 作为一名消费者的使用流程 ....................................................... 4 2.1.2 作为一名商城管理员的使用流程 ............................................... 5 2.2 网上商城模块分析 .............................................................................. 5 2.2.1 用户模块分析 ............................................................................... 6 2.2.2 管理员模块分析 ........................................................................... 6 2.3 本章小结 .............................................................................................. 7 第3章 网上商城系统的设计与实现 ........................................................... 8 3.1 开发语言和工具介绍 .......................................................................... 8 3.1.1 开发语言介绍 ............................................................................... 8 3.1.2 数据库介绍 ................................................................................... 9 3.1.3 服务器介绍 ................................................................................... 9 3.1.4 开发工具介绍 ............................................................................. 10 3.2 业务逻辑设计 .................................................................................... 10 3.2.1 基础共用类和相应方法 ............................................................. 10 3.2.2 用户实体类和相应方法 ............................................................. 14 3.2.3 管理员实体类和相应方法 ......................................................... 15 3.2.4 商品类别类和相应方法 ............................................................. 16 3.2.5 商品类及其相应管理方法 ......................................................... 17 3.2.6 购物车类及其方法 ..................................................................... 18 3.2.7 订单类及其方法 ......................................................................... 19 - III - 哈尔滨理工大学学士学位论文 3.3 数据库设计 ........................................................................................ 21 3.3.1 数据库设计简要介绍 ................................................................. 21 3.3.2 数据库具体设计 ......................................................................... 22 3.4 本章小结 ............................................................................................ 24 第4章 系统的测试和分析 ......................................................................... 25 4.1 V0.1版本 ............................................................................................ 25 4.2 V0.2版本 ............................................................................................ 28 4.3 V0.3版本 ............................................................................................ 30 4.4 V0.4版本 ............................................................................................ 33 4.5 V0.5版本 ............................................................................................ 34 4.6 V0.6版本 ............................................................................................ 35 4.7 V0.7版本 ............................................................................................ 37 4.8 V0.8版本 ............................................................................................ 40 4.9 V0.9版本 ............................................................................................ 43 4.10 V1.0版本 .......................................................................................... 44 4.11 本章小结 .......................................................................................... 52 结 论 ....................................................................................................... 53 致 谢 ....................................................................................................... 54 参考文献 ....................................................................................................... 55 附 录 ....................................................................................................... 56 - IV - 哈尔滨理工大学学士学位论文 第1章 绪论 1.1 选题目的和意义 对于网上商城来说,我想每个人都不陌生,即使你没有亲自在网上买过东西也一定见过、听说过网上购物这种方式。网络购物作为一种新的购物形式已经被广大群众所接受,尤其是年轻群体,他们特别热衷于网购。 网购最大的优势就是东西要比现实中商场里的商品便宜,而且一般都是送货上门,因为网购一般都是采取快递送货方式,直接送到你家楼下或者公司里,因此网络购物的第二大优势就是其便利性,用户只要坐在电脑前,点点鼠标就可以买东西了。当然网购也有它的缺点,比如无法见到实物,只能通过商家介绍的文字和图片来了解商品,再比如买衣服无法试穿,而且这也为不良商家提供了忽悠消费者的方法,他们会尽力美化自己的商品来诱惑消费者买单,而消费者收到商品后才发现和想象中的差异很大,而商家又以各种各样的理由推脱,而且由于采用网上交易,所以会存在安全问题。但是这些都不能挡住网购的魅力,网上购物现在正变得越来越流行,市场份额也变得越来越大。因此这次毕业设计题目就以目前现有的网上商城系统为研究对象,例如淘宝和当当,这里主要研究后者的形式,也就是商城自己经营的方式,研究一般的网上商城的业务流程,猜测其各个功能模块及其组合、连接方式,并分析其具体的实现方式,最后使用Java加web服务器和数据库完成一个网上商城系统的主要功能模块。 通过这样一个毕业设计,可以提高自己Java编程的水准,也练习了怎样构建一个完整的系统,从系统的需求分析到设计,直至编码、测试并运行,熟悉并掌握一个完整的Web开发流程,为今后工作打下基础。 1.2 论文研究内容 网上商城是一个基于Internet的应用,属于B/S架构,前端就是一个客户浏览器,客户需要通过浏览器来访问服务器,因此,本文主要研究的就是一个网上商城系统(商城自负经营的类型)的业务流程及其实现方式。 首先,需要站在使用者的角度去思考你究竟会怎么使用这个系统,而一个网上商城的使用者一般又有两类,一类是普通消费者,而另一类则是商城的管理员,因此我就需要思考这两类人都会怎么来是使用这个系统,这样就能分析出网 - 1 - 哈尔滨理工大学学士学位论文 上商城系统的业务流程。 而实现这个业务流程可以采用很多种不同的方法,很明显,网上商城系统是一个基于Internet的应用,因此就需要使用到Web开发的方法,目前Web开发的方法有很多,流行的有Java和.Net,这里我选择了Java,因此我就需要研究如果采用Java作为编程语言,我应当如何来实现这个系统,这个系统应该划分为多少个模块,每个模块的功能又是什么,他们之间如何组合到一起,这也就是系统的设计。 而到了实际的代码开发阶段,也会碰到一些各种各样的问题,这也需要思考并解决。因此,本文的研究内容囊括了系统的分析、设计和编码,是在研究一个完整的Web开发流程。 1.3 什么是网上商城 为了正确的开发一个系统,你首先就需要全面的了解一个系统,它究竟是个什么东西,它为什么要这个样子,因此在这里就介绍什么是网上商城。 网上商城类似于现实世界当中的商店,差别是利用电子商务的各种手段,达成从买到卖的过程的虚拟商店,从而减少中间环节,消除运输成本和代理中间的 [1]差价,造就对普通消费,和加大市场流通带来巨大的发展空间。尽能的还消费者以利益,带动公司发展和企业腾飞,引导国民经济稳定快速发展,推动国内生产总值。 网上商城的出现一是因为技术的进步,Internet愈发发达,现在全世界都在使用Internet,而基于Internet的应用也越来越多;再就是人们思维方式的转变,不再拘泥于现实中的世界,喜欢畅游在虚拟的世界中,在网上交友,聊天,因此在网上购物也就诞生了,到了今天网上购物也变得越来越流行,市场份额也逐渐扩大。网上商城是在为个人用户和企业用户提供人性化的全方位服务,努力为用户创造亲切、轻松和愉悦的购物环境,不断丰富产品结构,最大化地满足消费者日趋多样的购物需求,并凭借更具竞争力的价格和逐渐完善的物流配送体系等各项优势,赢得市场占有率多年稳居行业首位的骄人成绩,也是时代发展的趋势。 当然,一种事物的出现必然伴随着它的两面性,它有它的优点,也有缺点,而网上商城的优点就是便宜,再就是便利性。在网上买东西一般都会比现实中的便宜一些,因此就吸引了很多的消费者购买;再者,网购一般都是快递送货,直接送到家门口或者公司里,这就使许多不愿意或者懒得逛街的人们提供了方便,坐在电脑前,只要点点鼠标就能买东西。而网上商城的缺点也是显而易见的,最 - 2 - 哈尔滨理工大学学士学位论文 大的缺点就是你无法见到实物,你对商品的了解仅能通过商家的文字和图片介绍,因此,在网上买的东西拿回来之后就有可能发现与想象中的相差很大,尤其是衣服,你无法试穿,买回来可能就不合适,其颜色、质地也可能有较大出入,而商家通常拒绝更换和退掉因为颜色和质地与想象不同的东西,而且网上还有很多假货,看上去很便宜,但是买回来却发现上当受骗;再就是网上交易存在风险,你的银行账号和密码有可能被不法分子盗取,你的个人信息也可能泄露,给你的工作和生活带来不便,因此网购时要注意保护你的密码和个人信息。 1.4 网上商城的分类 网上商城主要有三大类: B2B(Business To Business, 商家对商家)、B2C(Business To Customer,商家对顾客直销)和C2C(Customer to Customer,客户和客户),还有就是G2C(Government to Citizen)其功能不尽相同。 B2B的典型代表有阿里巴巴,中国制造网,主要是从事批发业务;B2C的典型代表有当当网,卓越,八点商城,问学商城,主要是从事零售业务;C2C的典型代表有淘宝、易趣、拍拍、百度有啊。G2C:G2C电子政务是指政(Government)与公众(Citizen)之间的电子政务。是政府通过电子网络系统为公民提供各种服务。G2C电子政务所包含的内容十分广泛,主要的应用包括:公众信息服务、电子身份认证、电子税务、电子社会保障服务、电子民主管理、电子医疗服务、电子就业服务、电子教育、培训服务、电子交通管理等。G2C电子政务的目的是除了政府给公众提供方便、快捷、高质量的服务外,更重要的是可以开辟公众参政、议政的渠道,畅通公众的利益表达机制,建立政府与公众的良性互动平台。而在这里,主要研究的是B2C(Business To Customer,商家对顾客直销)方式。 - 3 - 哈尔滨理工大学学士学位论文 第2章 网上商城系统的需求分析 2.1 网上商城业务流程分析 开发一个项目,不管你采用什么实现方式,其实都是在完成其业务流程,因此,将一个系统的业务流程分析清楚,将为后面的开发提供极大的便利。由于本文选择了B2C(Business To Customer,商家对顾客直销)模式,所以之后的分析或讨论均是针对此种模式。 如何对一个系统进行分析有很多的方法,这里我采用了站在具体的使用者的角度来考虑这个网上商城系统的功能和结构,先是粗略的分析一下使用的流程,在这个过程中就能够发现一些必须的基础的类。 2.1.1 作为一名消费者的使用流程 如果一个消费者第一次来到一个网络商城,他一般会先浏览浏览商品,看看他是否喜欢这个商城,因此,目前的网上商城大多在首页就会显示商品,用户也不需要登录就可以查看。 接下来如果他对这个商城感兴趣,那消费者一般会注册一个账号,以便以后使用,那么商城就需要提供用户注册功能;既然提供了注册功能就需要提供登录功能,用户登录之后应当显示这个用户。 用户登录之后就会拥有一定的权限,比如查看自己的个人信息,修改自己的个人信息,修改自己的密码等,当然登录用户也可以查看商品,最重要的,登录用户可以选择商品放入自己的购物车并下单结账。还可以查看自己所下的订单。 因此从上面的分析,我们大致可以分析出来有这么几个实体类来支撑这些操作,首先,如果要浏览商品,那么商品这个东西需要包装成一个实体类,才能在系统中向用户展示;再者用户注册会员,那么会员就又应该是一个实体类,你得在这个实体类里记录注册会员的一些信息啊,什么用户名啊、密码啥的;再者,用户选择了商品放入了购物车,那么购物车就又是一个实体类,它应当负责记录用户买了什么东西,也就是记录用户拿的哪些个商品;最后会员买完东西后给商城下了订单,那么这个订单也需要包装成一个实体类,上面需要记录一些信息,最主要的信息应当有:谁下了这个订单,买了什么东西,多少钱,其它的诸如什么时候下的也可以记录。 - 4 - 哈尔滨理工大学学士学位论文 2.1.2 作为一名商城管理员的使用流程 管理员首先要登录才能拥有操作,商城管理员应当能管理商城注册的会员:可以查看商城的注册会员,并且可以修改某个会员的信息,还可以删除会员。 商城管理员应当能管理商品,和商品的类别:可以查看商品类别,添加、修改和删除商品的类别;可以查看商品,添加、修改和删除商品。 商城管理员可以管理会员所下的订单:查看订单和处理订单。 管理员也可以修改自己的密码。 从管理员的操作,我们也可以得到这么几个实体类。第一,管理员,既然有管理员那么就必须有一个类来记录这些东西;第二,这里提到了商品的类别,那么这个也应当包装成一个类,而且这个类应当和商品类有一定的关联。 因此,从前面两个站在不同角度来分析使用流程来看,我从中提取出了一些个名词,这写个名词也就成为了一些基础的实体类,目前分析的出来的有,用户类、管理员类、商品类别类、商品类、购物车类、订单类。 这些个类都是明显的,但是还有一些类可能不能这样直接的通过找名词来得出来,但是可以分析这个过程,来将其推算出来。商城肯定是要用数据库的,那么对数据库的通用操作通常也会封装成为一个JDBC的类。随着分析的不断深入,还会有一些类不断地冒出来。这里我想采用的是实体类只是纯纯的实体类,只是包装一些属性,有一些简单的读取和设置方法,再专门写一个管理类来提供一些和这个实体类相关的一些业务所需的操作,那么这里就又得到了一些类:用户管理类、管理员管理类、商品类别管理类、商品管理类、购物车管理类和订单管理类。 当然这肯定不是全部,随着分析设计的深入,还会有一些类添加进来,就算进入到实际开发阶段,还有可能突然觉得需要再加入某个类。 2.2 网上商城模块分析 现在我再从另一个方面着手,来分析这个网上商城系统。那就是按照功能划分模块的分析方法。基本上每个系统基本上会划分为若干个不同的模块,以方便管理和维护。因此,在这里我也把我的这个网上商城系统按照功能划分为两大模块,管理员模块和用户模块,这两个模块又可以划分为若干个子模块。 - 5 - 哈尔滨理工大学学士学位论文 2.2.1 用户模块分析 用户模块是为商城的前台展示所设计的,用户模块又可以大致划分为一下子模块: 1(用户注册模块 2(用户登录模块 3(用户信息修改模块 4(修改用户密码模块 5(商品展示模块 6(购物车模块 7(查看以往订单模块 用户注册模块负责新会员注册,并将其持久化,也就是将新注册的会员的信息写入数据库。登录模块负责验证会员的登录,看看有没有这个用户,密码是否正确等,这种操作通常都是从数据库查询。用户信息修改模块可以让用户修改自己的个人信息,这就涉及到了数据库的修改。修改用户密码模块让用户修改自己的密码。商品展示模块应当是从数据库中将商品拿出来,然后再以某种方式显示的网页上。购物车模块就是收集和记录用户所购买的商品,购物车最后要么被直接销毁,要么会转化为订单,然后被销毁。查看以往订单模块使用户能查看自己所下的订单。因此数据库的操作始终贯穿在整个系统里面,几乎所有的地方都涉及到了数据库的操作。 2.2.2 管理员模块分析 管理员模块是为管理员管理商城事物所设计的,管理员模块又可以初步划分为以下子模块: 1(会员管理模块 2(商品类别管理模块 3(商品管理模块 4(订单处理模块 5(管理员的自我管理 很明显,会员管理模块是用来管理商城的注册会员的,应当可以查看会员、修改会员信息、删除会员,这就是对数据库的增删改查的体现。商品类别管理模块用来管理商品类别,可以查看商品类别,添加商品类别,修改商品类别和删除 - 6 - 哈尔滨理工大学学士学位论文 商品类别。商品管理模块用来管理商城的商品,可以查看商品,添加商品,修改商品和删除商品。订单处理模块用来管理会员所下订单,可以查看会员所下的订单,并处理这些订单。 这里又把这个网上商城系统分成了两个模块,用户模块和管理员模块,这两个模块又可以具体分为若干个小模块,这么做的目的就是使整个系统更加的清晰明了,更加的有层次感,而且通过不同角度的分析,可以让我更好地去理解这个网上商城系统的结构以及它的组合方式。 2.3 本章小结 本章主要从商城的使用者角度,也就是普通用户和商城管理员两方面分别分析了这些用户对商城一般的操作流程。然后根据这些流程分析出了一些直接的类,也就是一些基础的实体类,并跟据这些大致的流程分析出两个大模块,用户模块和管理员模块,两个大模块又可以进一步细分为一个个小模块。并大致分析了这些模块的功能。 - 7 - 哈尔滨理工大学学士学位论文 第3章 网上商城系统的设计与实现 本章是网上商城系统的具体设计,包括开发环境的选择及介绍,各个功能模块的具体设计以及一部分实现。 3.1 开发语言和工具介绍 这里介绍我选择的开发语言,开发工具等。 3.1.1 开发语言介绍 1(Java简介:Java是一种简单的,面向对象的,分布式的,解释型的,健壮安全的,结构中立的,可移植的,性能优异、多线程的动态语言。 Java平台由Java虚拟机(Java Virtual Machine)和Java 应用编程接口 [2](Application Programming Interface、简称API)构成。Java 应用编程接口为Java应用提供了一个独立于操作系统的 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个Java平台之后,Java应用程序就可运行。现在Java平台已经嵌入了几乎所有的操作系统。这样Java程序可以只编译 一次,就可以在各种系统中运行。 Java分为三个体系JavaSE(Java2 Platform Standard Edition,java平台标准版),JavaEE(Java 2 Platform,Enterprise Edition,java平台企业版),JavaME [3](Java 2 Platform Micro Edition,java平台微型版)。 2(HTLM简介:HTML(HyperText Mark-up Language)即超文本标记语言 [4]或超文本链接标示语言,是目前网络上应用最为广泛的语言,也是构成网页文档的主要语言。HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字、图形、动画、声音、表格、链接等。HTML的结构包括头部(Head)、主体(Body)两大部分,其中头部描述浏览器所需的信息,而主体则包含所要说明的具体内容。 3(JavaScript简介:Javascript是一种由Netscape的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如Perl,遗留的速度问题,为客户提供更流畅的浏览效 [5]果,并且能为在客户端就进行数据的验证。 4(AJAX简介:AJAX即“Asynchronous JavaScript and XML”(异步 - 8 - 哈尔滨理工大学学士学位论文 [6]JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。 5(JSP/Servlet简介:JSP(Java Server Pages)是由Sun Microsystems公司倡 [7]导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。 Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可 [8]以生成动态的Web页面。它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。 Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机。 3.1.2 数据库介绍 [9]MySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司。在2008年1月16号被Sun公司收购。目前MySQL被广泛地应用在Internet上的中小型网站中。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。MySQL的官方网站的网址是:www.mysql.com。 3.1.3 服务器介绍 Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项 [10]目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。目前最新版本是6.0。 Tomcat 是一个小型的轻量级应用服务器,在中小型系统和并发访问用户不 [11]是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。另外,Tomcat和IIS、Apache等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。 - 9 - 哈尔滨理工大学学士学位论文 3.1.4 开发工具介绍 在开发工具选择方面,我选择了MyEclipse、Dreamweaver作为主要开发工具,还使用到了UltraEdit、MySQL Workbench等。 1(MyEclipse介绍:MyEclipse企业级工作平台(MyEclipse Enterprise Workbench ,简称MyEclipse)是对Eclipse IDE的扩展,利用它我们可以在数据库和JavaEE的开发、发布,以及应用程序服务器的整合方面极大的提高工作 [12]效率。它是功能丰富的JavaEE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML, Struts, JSF, CSS, Javascript, SQL, Hibernate。 2(Dreamweaver介绍:Macromedia Dreamweaver是个由Macromedia公司开发的著名网站开发工具,它使用所见即所得的界面,亦有HTML编辑的功能[13]。它现在有Mac和Windows系统的版本。一个可视化的网页设计和网站管理工具,支持最新的Web技术,包含HTML检查、HTML格式控制、HTML格式化选项、HomeSite/BBEdit捆绑、可视化网页设计、图像编辑、全局查找替换、全FTP 功能、处理Flash和Shockwave等富媒体格式和动态HTML、基于团队 的Web创作。在编辑上可以选择可视化方式或者喜欢的源码编辑方式。 3.2 业务逻辑设计 要实现网上商城的业务逻辑,必须有相应的实体类和其相应的方法,这里就大致将其设计出来。 3.2.1 基础共用类和相应方法 整个系统有一些通用的类和方法,比如连接数据库等。 3.2.1.1 DB类 方法: 1(public static Connection getConn() 取得用于连接数据库的Connection。 2(public static void close(Connection conn) 关闭Connection。 3(public static void close(Statement stmt) 关闭Statement。 4(public static void close(ResultSet rs) 关闭ResultSet。 3.2.1.2 系统基础配置 文件来储存一些基本的系统设置,比如数据库连接设置。 这里采用xml sys-config.xml - 10 - 哈尔滨理工大学学士学位论文 com.mysql.jdbc.Driver jdbc:mysql://localhost/shopping root root 这里储存了数据库连接的Driver和url以及用户名和密码,当连接数据库时,就会从这里读取配置信息,当配置信息改变时,直接在这里修改,而不再需要改代码了。 3.2.1.3 JdbcConfig类 JdbcConfig类就包装了上面sys-config.xml配置文件所配置的数据库连接信息。 成员变量: 1(private String driverName 数据库连接的Driver。 2(private String url 数据库连接字符串。 3(private String userName 用户名。 4(private String password 密码。 方法: getters()和setters()方法,用来得到和设置成员变量的值,因此不详细列出。 3.2.1.4 XmlConfigReader类 XmlConfigReader是负责在连接数据库是从sys-config.xml文件里读取配饰,采用了单例模式,只在第一次加载时读取一次,并保存到jdbcCofig类中,再次连接时直接从jdbcConfig类中读取,XmlConfigReader使用了开源的dom4j来读取xml文件。 成员变量: 1(private static XmlConfigReader instance XmlConfigReader的实例。 2(private JdbcConfig jdbcConfig jdbcConfig类的实例。 方法: private XmlConfigReader() { SAXReader reader = new SAXReader(); - 11 - 哈尔滨理工大学学士学位论文 InputStream is = Thread.currentThread().getContextClassLoader() .getResourceAsStream("sys-config.xml"); try { Document doc = reader.read(is); //获取jdbc配置信息 Element driverNameEle = (Element) doc.selectObject("/config/db- info/driver-name"); Element urlEle = (Element) doc.selectObject("/config/db-info/url"); Element userNameEle = (Element) doc.selectObject("/config/db- info/user-name"); Element passwordEle = (Element) doc.selectObject("/config/db- info/password"); //设置jdbc配置信息 jdbcConfig.setDriverName(driverNameEle.getStringValue()); jdbcConfig.setUrl(urlEle.getStringValue()); jdbcConfig.setUserName(userNameEle.getStringValue()); jdbcConfig.setPassword(passwordEle.getStringValue()); } catch (DocumentException e) { e.printStackTrace(); } } XmlConfigReader类的构造方法,在这里采用的dom4j来读取sys-config.xml 文件的内容,首先通过ClassLoader把sys-config.xml文件当做一个输入流并交给 SAXReader的对象reader,reader就会通过查找标签的方式来把这个标签当做一 个Element对象读取上来,例如Element driverNameEle = (Element) doc.selectObject("/config/db-info/driver-name");就会吧sys-config.xml中的com.mysql.jdbc.Driver这对标签当做Element对象读取上 来,实际上SAXReader是将xml文件当做一颗dom树并读取其上的内容的。再 通过driverNameEle.getStringValue()就能将标签中的值拿到,也就是 com.mysql.jdbc.Driver,然后再把它设置到jdbcConfig中,这样再调用的时候就 去jdbcConfig中读取。整个构造方法执行完毕后,sys-config.xml文件里得内容 就会全部被读取上来并保存到jdbcConfig中。 public static synchronized XmlConfigReader getInstance() 取得 - 12 - 哈尔滨理工大学学士学位论文 XmlConfigReader的实例。 public JdbcConfig getJdbcConfig() 取得jdbcConfig。 3.2.1.5 PageModel类 PageModel包装了分页信息。 成员变量: 1(private List list 一个被包装的结果集,如果是User就是一个 UserList。 2(private int totalRecords 总记录数。 3(private int pageSize 每页记录数。 4(private int pageNo 当前页码。 方法: getters()和setters()方法,用来得到和设置成员变量的值,因此不详细列出。 3.2.1.6 CharsetEncodingFilter类 这是一个filter,用来为jsp页面统一设置request字符集,使得每个jsp页面不再需要单独设置,而且也为修改配置带来了方便,它同样从xml文件中读取配置信息。 成员变量: 1(private String charsetEncoding 字符集设置。 方法: 1(public void destroy() 销毁这个filter。 2(public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 在这里统一为jsp页面设置request字符集。 3(public void init(FilterConfig filterConfig) filter的初始化方法,filter会在 Web server启动时被初始化,在这里读取了保存在web.xml文件里的配 置filterConfig.getInitParameter("charsetEncoding"),并且将其保存在了 charsetEncoding里。下面是其配置信息: charsetEncoding GB18030 Filter需要在web.xml文件里配置一下才能生效,且需要配置其作用范围: CharsetEncodingFilter - 13 - 哈尔滨理工大学学士学位论文 com.jinyize.shopping.util.filter.CharsetEncodingFilter charsetEncoding GB18030 CharsetEncodingFilter *.jsp 标签是为这个filter设置名字。 标签是标识这个filter的类的具体位置。 标签可以放置一些filter的初始化参数。 *.jsp标签标示了这个filter的作用域,*.jsp就标示对所有的jsp页面起作用。 3.2.2 用户实体类和相应方法 为了实现商城会员的注册、登录、查看会员自己的信息、修改会员的个人信息、修改个人密码和查看所下的订单,应当有一个用户实体类和其相应的方法,在这里设计出两个类User和UserManager类。User只是包装用户的信息,并提供相应的get和set方法;UserManager则提供和User相关的各种业务逻辑方法。 3.2.2.1 User类 成员变量: 1(private int id 用户id。 2(private String username 用户名。 3(private String password 密码。 4(private String phone 联系电话。 5(private String address 送货地址。 6(private String email Email。 7(private Date rDate 注册日期。 方法: - 14 - 哈尔滨理工大学学士学位论文 getters()和setters()方法,用来得到和设置成员变量的值,因此不详细列出。 3.2.2.2 UserManager类 成员变量: 1(private static UserManager instance UserManager自己的实例化(单例模 式)。 方法: 1(public static UserManager getInstance() 取得UserManager的实例。 2(public boolean addUser(User u) 添加用户。 3(public User findUserByName(String userName) 通过用户名查找用户。 4(public User findUserById(String userId) 通过用户id查找用户。 5(public User login(String userName, String password) 验证用户登录。 6(public boolean modifyUser(User u) 修改用户信息。 7(public boolean delUser(String[] userIds) 删除用户。 8(public PageModel findUserList(int pageNo, int pageSize) 取得用户的 分页信息。 9(public PageModel findUserList(int pageNo, int pageSize, String text, String flag) 取得用户的分页信息。 3.2.3 管理员实体类和相应方法 用以实现商城管理员的登录和修改密码。 3.2.3.1 Admin类 包装了管理员的属性。 成员变量: 1(private String userName 用户名。 2(private String password 密码。 方法: getters()和setters()方法,用来得到和设置成员变量的值,因此不详细列出。 3.2.3.2 AdminManager类 提供了管理员类的相应管理方法。 成员变量: 1(private static AdminManager instance 单利模式的AdminManager实例。 方法: 1(public static AdminManager getInstance() 取得AdminManager实例。 - 15 - 哈尔滨理工大学学士学位论文 2(public Admin login(String userName, String password) 验证管理员登录。 3(public boolean modify(Admin admin) 修改密码。 3.2.4 商品类别类和相应方法 这是一个基础的类,它是一种树形结构,有根类别,其下又有很多子类别, 一个商品必须属于某种商品类别。 3.2.4.1 Category实体类 包装了商品类别的属性。 成员变量: 1(private int id Category的id。 2(private int pid 父类别的id。 3(private String name 类别的名称。 4(private String describe 类别的描述。 5(private int grade 类别的级别。 6(private boolean leaf 是否是叶子节点。 方法: getters()和setters()方法,用来得到和设置成员变量的值,因此不详细列出。 3.2.4.2 CategoryManger管理类 提供一系列管理商品类别的方法,单例模式。 成员变量: 1(private static CategoryManager instance 单例模式的管理类。 方法: 1(public static CategoryManager getInstance() 取得CategoryManager的实 例。 2(public String getCategoryTreeHTMLString() 取得类别树形结构的HTLM 字符串,这里实际上是调用了另一个类的方法。 3(public List getCategoryList() 取得Category的树形结构并放入 List里返回,这里也是调用另一个类的方法。 4(public List getTopCategoryList() 取得顶级的类别节点,也是通 过调用另一个类的方法。 5(public Category findCategoryById(int id) 通过id查找类别。 6(public boolean addCategory(Category c) 添加一个商品类别。 7(public boolean modifyCategory(Category c) 修改一个商品类别。 - 16 - 哈尔滨理工大学学士学位论文 8(public boolean delCategory(Category c) 删除一个商品类别及其子类别。 9(private void delCategory(Connection conn, int id) throws SQLException 被 public boolean delCategory(Category c)方法调用的,用来递归删除一个类 别的子节点的私有方法。 3.2.4.3 CategoryTreeReader类 这个类就是负责从数据库中将Category的树形结构读取出来,所有的方法 都被CategoryManager类重新包装。 方法: 1(public String getCategoryTreeHTMLString() 对外提供的公共方法,以取得 类别树并组成HTML字符串,以供网页显示出一个树形结构。 2(private void getCategoryTree(Connection conn, StringBuffer strBuf, int id, int level) throws SQLException 取得HTML字符串的具体实现方法,被 public String getCategoryTreeHTMLString()方法调用。 3(public List getCategoryList() 取得商品类别的树形结构并放入 一个List中。 4(private void getCategoryList(Connection conn, List categoryList, int pid) throws SQLException 取得Category的树形结构的具体实现。 5(public List getTopCategoryList() 取得顶级的类别节点。 3.2.5 商品类及其相应管理方法 记录并保存商品,提供一系列的管理方法。 3.2.5.1 Product实体类 包装了产品的属性,依存于Category类。 成员变量: 1(private int id 商品的id。 2(private String name 商品的名称。 3(private String brand 品牌。 4(private String describe 商品的描述。 5(private double normalPrice 市场价格。 6(private double memberPrice 会员价格。 7(private Date pDate 商品的上架日期。 8(private Category category 商品所属的类别。 9(private String fileName 商品的图片文件的名称。 - 17 - 哈尔滨理工大学学士学位论文 方法: getters()和setters()方法,用来得到和设置成员变量的值,因此不详细列出。 3.2.5.2 ProductManager管理类 提供了一系列的管理商品的方法,采用单例模式。 成员变量: 1(private static ProductManager instance ProductManager类的单例对象。 方法: 1(public boolean addProduct(Product p) 添加商品。 2(public PageModel findProductList(int pageNo, int pageSize, boolean lazy) 取得商品的列表。 3(private int getTotalRecords(Connection conn) throws SQLException 得到数 据库中商品的总记录数。 4(public Product findProductById(int id, boolean lazy) 通过id查找商品。 5(public boolean modifyProduct(Product p) 修改一个商品。 6(public boolean delProducts(String[] pIds) 批量删除商品。 7(public PageModel findProductList(int pageNo, int pageSize, boolean lazy, String text) 搜索商品。 8(public PageModel findProductList(int pageNo, int pageSize, boolean lazy, Category category, String text) 搜索商品。 9(public boolean uploadProductPicture(int id, String fileName) 将商品图片的 文件名称保存到数据库中。 3.2.5.3 FileUploadServlet Servlet,用来实现为商品上传图片,用到了apache的commons-fileupload和commons-io组件,这是在Java的Web开发中最常用的文件上传组件。上传的图片会存放在服务器的目录下。 3.2.6 购物车类及其方法 购物车在所有的网上商城系统中都是非常重要的一块,用户一般都是先将商品放入自己的购物车,然后再下单结账,这里设计了三个类,一个是购物车主体类,用来存放一些主要的信息,还有一个类专门用来存放具体的购物项,之后还有一个管理类来对外提供各种服务。 3.2.6.1 ShoppingCart实体类 这个类保存了购物车的一些主要信息,如购物项的列表,而具体的每一个的 - 18 - 哈尔滨理工大学学士学位论文 购物项则保存在另一个类中。 成员变量: 1(private List cartItems 一个购物项的列表。 方法: 1(public List getCartItems() 取得购物项的列表。 2(public void setCartItems(List cartItems) 设置购物项的列表。 3(public void add(CartItem cartItem) 添加购物项。 4(public void deleteItemById(int productId) 删除购物项。 3.2.6.2 CartItem类 这个类存放着具体购物项的信息,比如商品和购物数量。 成员变量: 1(private Product product 商品。 2(private int count 数量。 方法: 1(public Product getProduct() 取得商品。 2(public void setProduct(Product p) 设置商品。 3(public int getCount() 取得购物数量。 4(public void setCount(int count) 设置购物数量。 5(public double getTotalMemberPrice() 取得此购物项的会员价的合计金额。 6(public double getTotalNormalPrice() 取得此购物项的市场价的合计金额。 3.2.6.3 ShoppingCartManager管理类 它对外提供一系列的方法以供对购物车进行操作,仍然是单例模式。 成员变量: 1(private static ShoppingCartManager instance 单例的ShoppingCartManager 类的实例。 方法: 1(public double getTotalNormalPrice(ShoppingCart shoppingCart) 取得购物车 的市场价总价。 2(public double getTotalMemberPrice(ShoppingCart shoppingCart) 取得购物 车的会员价总价。 3.2.7 订单类及其方法 订单是用户在将购物车内的物品结账时产生的,因此订单类的成员变量合法 - 19 - 哈尔滨理工大学学士学位论文 和购物车的很相似,这里也是设计了三个类,一个订单的主类,用来保存订单的 主要信息,比如谁下的订单,送货的地址在哪里,什么时候下的订单等,而具体 订单上的每一个购物项存放在一个专门的类里,当然也有一个管理类向外提供方 法。 3.2.7.1 Order订单实体类 这个类包装了订单的主要信息,比如谁下的订单,送货的地址在哪里,什么 时候下的订单等。 成员变量: 1(private int id 订单的id。 2(private User user 下单用户。 3(private String address 送货地址。 4(private Date oDate 下单日期。 5(private int status 订单状态。 6(private List items 购物项列表。 方法: 1(getters()和setters()方法。 2(public void add(OrderItem item) 添加购物项。 3.2.7.2 OrderItem类 这个类存放具体购物项的信息。 成员变量: 1(private int id 购物项的id。 2(private Product product 商品。 3(private double price 购买时的价格。 4(private int count 数量。 5(private int orderId 所属订单的id。 方法: 1(getters()和setters()方法。 2(public double getTotalPrice() 取得此购物项的合计金额。 3.2.7.3 OrderManager管理类 单例模式的管理类,对外提供一些方法用于操作订单。 成员变量: 1( private static OrderManager instance 单例的OrderManager 对象。 方法: - 20 - 哈尔滨理工大学学士学位论文 1(public boolean saveOrder(Order order) 将订单保存到数据库中。 2(public PageModel getOrdersByUser(int pageNo, int pageSize, User user, boolean lazy) 查找某一用户的全部订单。 3(private void getOrderItemListById(Connection conn, int id, List itemList, boolean lazy) throws SQLException 查找一个订单的具体订单 项。 4(private int getTotalRecords(Connection conn, User user) throws SQLException 取得属于某一用户的订单的总记录数。 5(public double getTotalPrice(Order order) 取得这个订单的总金额。 6(public List getOrderItemById(int id, boolean lazy)public List getOrderItemById(int id, boolean lazy) 取得某一订单的全 部订单项。 7(public PageModel getOrders(int pageNo, int pageSize, boolean lazy) 取得数据库中的所有订单。 8(private int getTotalRecords(Connection conn) throws SQLException 取得数 据库中全部订单的记录数。 9(public boolean delOrders(String[] ids) 批量删除订单。 10(public PageModel getPendingOrders(int pageNo, int pageSize, boolean lazy) 取得全部的未处理订单。 11(public Order getOrderByID(int id, boolean lazy) 通过id查找订单。 12(public boolean dealOrderStatus(int id, int status) 修改订单的状态。 3.3 数据库设计 3.3.1 数据库设计简要介绍 在前面实体类设计完成之后,其实数据库的设计已经变得简单了,数据库表 就是前面实体类的成员变量的对应,这里设计了6张表,分别是: 1(user 用户表 2(admin 管理员表 3(category 商品类别表 4(product 商品表 5(salesorder 订单表 - 21 - 哈尔滨理工大学学士学位论文 6(salesitem 订单购物项表 这六张表其实分别对应了6个不同的实体类,User、Admin、Category、Product、Order和OrderItem。其中product表将category表的id字段作为外键,salesitem表将salesorder表的id字段作为外键。 下面就具体介绍每张表的具体设计。 3.3.2 数据库具体设计 3.3.2.1 user表 user表是用来存放商城会员的信息的表,有7个字段,分别用来存放用户id、用户名、密码、联系电话、送货地址、Email和注册日期,它又和User实体类的成员变量对应,详见表4-1。 表4-1 user表 字段名 字段类型 是否为主键 是否可为空 外键 描述 id Int(11) YES NO 用户id username varchar(40) YES 用户名 password varchar(20) YES 密码 phone varchar(40) YES 联系电话 addr varchar(255) YES 送货地址 email varchar(50) YES 电子邮箱 rdate datetime YES 注册日期 3.3.2.2 admin表 admin表用来存放管理员的用户名和密码,有2个字段,分别用来存放管理员的用户名和密码,它和Admin实体类对应。具体请见表4-2。 表4-2 admin表 字段名 字段类型 是否为主键 是否可为空 外键 描述 username varchar(20) YES NO 用户名 password varchar(40) YES 密码 3.3.2.3 category表 category表用来存放商品类别的信息,有6个字段,分别用来存放商品类别的id、其父类别的id、类别的名称、类别的描述、类别的级别和类别是否为叶子节点,详见表4-3。 - 22 - 哈尔滨理工大学学士学位论文 表4-3 category表 字段名 字段类型 是否为主键 是否可为空 外键 描述 id Int(11) YES NO 类别id pid Int(11) YES 父类别id name varchar(255) YES 类别名称 descr varchar(255) YES 类别描述 grade Int(2) YES 级别 isleaf Int(1) YES 是否为叶子 3.3.2.4 product表 product表用来保存商品的信息,有9个字段,分别用来保存商品的id、商品的名称、品牌、描述、市场价格、会员价格、上架日期、类别id和图片文件名,详见表4-4。 表4-4 product表 字段名 字段类型 是否为主键 是否可为空 外键 描述 id Int(11) YES NO 商品id name varchar(255) YES 商品名称 brand varchar(255) YES 品牌 descr varchar(255) YES 描述 normalprice double YES 市场价格 memberprice double YES 会员价格 pdate datetime YES 上架日期 categoryid Int(11) NO category.id 商品类别id filename varchar(255) YES 图片文件名 3.3.2.5 salesorder表 salesorder表用来存放订单的主信息,有5个字段,分别用来存放订单的id、用户id、送货地址、下单日期和订单状态,当然它会有一个从表,来存放具体的购物信息。详见表4-5。 表4-5 salesorder表 字段名 字段类型 是否为主键 是否可为空 外键 描述 id Int(11) YES NO 订单id userid Int(11) YES user.id 用户id addr varchar(255) YES 送货地址 odate datetime YES 下单日期 status Int(1) YES 订单状态 - 23 - 哈尔滨理工大学学士学位论文 3.3.2.6 salesitem表 salesitem表用来存放具体的订单项,有5个字段,分别用来存放订单项id、商品id、单价、数量和所属订单id,详见表4-6。 表4-6 salesitem表 字段名 字段类型 是否为主键 是否可为空 外键 描述 id Int(11) YES NO 订单项id productid Int(11) NO product.id 商品id unitprice double YES 单价 pcount Int(11) YES 数量 orderid Int(11) NO salesorder.id 所属订单id 3.4 本章小结 本章非常详细的介绍了网上商城系统的具体设计,从开发工具的选择和环境的搭建,到基础的共用类,到具体的实体类再到数据库的设计。这样就完成了项目具体框架的搭建。 - 24 - 哈尔滨理工大学学士学位论文 第4章 系统的测试和分析 从这里进入到具体的软件编码阶段,我采用了螺旋递增的方式开发,每个版本都只完成一定的功能,然后进行一定的测试,然后继续进行开发,继续完成和完善功能,直到所有的功能全部完成。 4.1 V0.1版本 在这个版本里,做了一些系统共用类的封装,比如对数据库操作的一些常用的方法,将其封装到了DB类中,封装了取得数据库连接Connection的方法,和关闭Connection、Statement和ResultSet的方法。在获得数据库连接Connection的时候需要提供一些信息,第一个是数据连接驱动的名字,第二个是数据库连接字符串,还有用户名和密码,这些信息如果写死在程序里面并不好,如果修改数据库那必须要重新修改程序,因此我将上面那些信息封装到了配置文件中,也就是sys-config.xml文件中,如果配置发生了变化,那只需要在配置文件中改动相应的配置即可。 XML文件目前非常的流行,因为用它来保存配置信息非常的方便,XML文件采用的是标记和值的方式,语法和HTML(超文本标记语言)类似,例如com.mysql.jdbc.Driver,在这条记录里的这对标记就相当于名字,当需要找里面的值的时候只需要找到它就行了,XML文件的机构是一颗树形机构,有根节点,然后是一层一层的分支节点,这也称之为DOM树,对XML文件的操作就是对这颗DOM树进行操作,所以这里我用到了开源的第三方组件DOM4J,用它来对XML文件进行操作,把其中的配置信息读取出来,供数据库调用时使用。 在网络编程中,中文乱码问题一直是个比较麻烦的事情,解决的方法就是在JSP页面或者Servlet里设置字符集,但是页面非常多的情况下,设置字符集就变得非常麻烦,而且如果发生变动,就需要将这些页面或Servlet的代码全部改一遍,所以这里引入了一个Filter,Filter是一个过滤器,属于面向切面编程的东西,它就是在原来的调用流程里无缝的切入了一层,来实现一些功能,下面我画图解释一下Filter的工作原理和调用流程,如图4-1。 - 25 - 哈尔滨理工大学学士学位论文 Tomcatservlet 1: 调用 图4-1 普通调用流程 在没有加入Filter之前,一个请求到达时,Tomcat会帮忙调用相应的JSP或者Servlet,如果加入了Filter则变成了图4-2所示的样子。 TomcatFilterServlet 1: 调用 2: doFilter() 图4-2 加入Filter之后的调用流程 如果加入了一个Filter,则会变成这个样子,也就是在原先的Tomcat调用Servlet之间又切入了一层,正因为切入了这么一层,所以在这一层就可以做一些事情,在这里我设置了字符集,之后又通过doFilter()方法继续调用Servlet,这种切入是无缝的,不会影响之前的任何东西。 在这个版本里,我还建立了User实体类和UserManager管理类,User类封装了会员的信息,UserManager则提供了一系列的管理方法,有了这两个类接下来就完成了用户的注册和登录功能,在用户注册的时候采用了AJAX来验证用户名是否已经被注册过了,如果已经被注册过了就会在用户名的输入框后面显示一行红字,说用户名已经存在了,如果没有被注册过则显示一行绿字,说可以使用这个用户名注册,在注册页面还使用了JavaScript来验证用户的输入,比如密码长度不能小于6位,两次密码输入的是否一致,如果输入了电话和Email则验 - 26 - 哈尔滨理工大学学士学位论文 证其合法性,送货地址不能为空。下面是界面截图,见图4-3。 图4-3 用户注册页面 所有的信息都无误时就可以注册了,如果成功则显示欢迎界面,如图4-4。 图4-4 注册成功页面 注册用户就可以登录了,在首页上有一个供用户登录的区域,在这里可以输 - 27 - 哈尔滨理工大学学士学位论文 入用户名和密码登录,见图4-5。 图4-5 主页上的用户登录 在这个登录框输入用户名和密码,如果正确就会转到用户欢迎页面,如果失败则提示用户名或者密码错误,如果用户登录成功了,就会将这个用户记录到Session中,在需要用户登录的页面就会检查这个Session,如果没有登录则会重定向到用户登录页面,让用户登录。 到这里,V1.0版本就完成了,经过测试也都没有问题。 4.2 V0.2版本 V0.2版本完成的是用户修改自己的信息和修改自己的密码,用户要修改自己的信息和密码前提是已经注册的用户,而且必须在已经登录的状态下,如果没有登录则会重定向到用户登录页面,用户登录页面见图4-6。 - 28 - 哈尔滨理工大学学士学位论文 图4-6 用户登录页面 如果是已经登录的用户则会显示如图4-4的欢迎页面,这里可以让用户选择干什么,如果是修改个人信息则进入个人信息修改页面,这里会把用户的信息完整的显示出来,用户就可以修改了,如图4-7。 图4-7 用户信息修改 - 29 - 哈尔滨理工大学学士学位论文 当用户输入新的信息并点击提交之后,就会把新的信息保存到数据库中,并重新在这个页面显示出来。 如果用户选择了修改密码,则会出现修改密码页面,这里会要求用户输入旧密码和新密码以及新密码的确认,在旧密码这里也采用了AJAX验证,如果输入不正确就会在输入框后面显示一行红色的文字,提示说原始密码不正确,如果出现这行字则会有JavaScript来限制用户无法提交,如果正确则会显示绿色的OK,新密码和新密码的确认也有JavaScript的验证,来验证长度是否符合,以及两次输入是否一致,如图4-8。 图4-8 用户修改密码 如果原始密码正确,新密码也符合要求,用户点提交之后就会在数据库中更新用户的密码。 到这里,V0.2版本就完成了,经测试,功能全部正常。 4.3 V0.3版本 完成了用户这边的一些东西,管理员那边也应该跟上,因此这个版本就是完成管理员的登录,以及查看、修改和删除会员。管理员的功能页面专门放到了一 - 30 - 哈尔滨理工大学学士学位论文 个admin文件夹下,以此和普通商城用户的功能相隔离,也更方便管理和维护,首先要实现的就是管理员登录页面,这个页面及其简单,只有俩输入框和俩按钮,如图4-9。 图4-9 管理员登录页面 输入用户名和密码之后,正确之后就转到主页面,否则提示出错。主工作页面是由三部分组成的,最上面是一个标题,左下方是一个操作栏,可以选择操作,又下方是工作区,如果进入之后选择商城会员管理,点击查看所有会员的图标,就会在工作区中将所有的会员显示出来,并提供分页,如图4-10。 图4-10 查看所有用户 - 31 - 哈尔滨理工大学学士学位论文 在这里会把所有已经注册的会员用表格罗列出来,上面有所有用户的信息,以供管理员管理。在最左边是一排复选框,只有选中之后才能对用户进行操作,如果是删除用户,选中几个就会删除几个,然后页面就刷新,就会看到那些用户不见了,如果是修改用户一次只能选择一个,否则不能执行,这里有JavaScript进行控制,修改用户信息的页面如图4-11。 图4-11 修改用户信息 在这里会把用户已有的信息显示到页面上,管理员可以修改密码联系电话Email和送货地址,这里也有JavaScript来验证输入的信息是否合法,其中UID和用户名是不可更改的,密码必须大于6位,两次输入的必须相同,当然,用户的密码已经取出来房到密码框里了,一般情况不用修改,除非用户的密码丢失了,要求管理员重置一个密码,联系电话和Email要么不输入,如果输入了就验证格式是否正确,电话号码必须为数字,Email也要符合格式,这些格式都是正则表达式来验证的。当点击修改后就会将新的信息保存到数据库中,并重新显示到此页上。 到这里V0.3版本就完成了,这个版本完成了管理员维护商城会员的功能,可以查看、修改和删除会员。这里就是用户完成一项功能后,管理员相应的功能也会跟上,然后继续开发用户的功能接着又是管理员的,如此往复循环,以完成整个项目。 - 32 - 哈尔滨理工大学学士学位论文 4.4 V0.4版本 V0.4版本是继续完善管理员对用户的管理,增加了搜索用户的功能,可以模糊搜索或者精确搜索,搜索页面见图4-12。 图4-12 用户搜索页面 在这里要求填写搜索的关键字,如果不填写则会弹出一个对话框提示搜索条件不能为空,模糊搜索会匹配用户名、联系电话和送货地址和Email,这里其实就是select * from user where (字段名) like (%条件%),只要是字段里还有被搜索的条件,都会被查询上来如果是精确搜索则只会精确匹配用户名,搜索结果的页面与全部用户的界面几乎相同,详见图4-13。 图4-13 用户搜索结果 同样的,在这里也可以对搜索出来的用户进行修改和删除操作,和全部用户那里是一样的。 V0.4版本实现的功能还有就是管理员自己修改自己的密码,同样这里也有用到AJAX来验证原始密码是否正确,AJAX会在后台请求到一个Servlet,Servlet再到数据库中查询看看原始密码是否输入正确,再将结果返回给客户端,如果没有输入正确则会提示原始密码不正确,并且不允许提交,新密码要求长度不能小于6位,两次输入必须相同,见图4-14。 - 33 - 哈尔滨理工大学学士学位论文 图4-14 管理员修改密码 全部输入正确之后,点击修改就会将数据库中的信息修改,并再次返回这个页面,在左上角会有提示说密码修改成功的字样。 这样V0.4版本就完成了。 4.5 V0.5版本 V0.5版本建立了Category类和他的管理类CategoryManager类,并且完成了从数据库中将商品类别的树形机构读取出来并显示到页面上,见图4-15。 图4-15 所有商品类别的树形展示 - 34 - 哈尔滨理工大学学士学位论文 因为Category类本身就是一种树状结构,一个大类别下面有包含有若干个子类别,子类别下面还可以有子类别,因此展现为一种树形结构最直观也最容易理解,当一个类别下面有子类别的时候,它前面就是一个+号,还有一个关闭的文件夹,当鼠标放到这个+号上的时候,会显示展开字样,当点击它的时候就会将其下面的子类别显示出来,同时他前面的+号也会变成一个,号,后面的文件夹也会变成一个打开的文件夹,这些都是由JavaScript来控制的,那个小+号其实是一张图片,当你点击它的时候,就会调用一个JavaScript方法,来使一个div变成显示状态,把那个小文件夹变成打开的图片,而这个div里就是它的子类别,如果子类别还有子类别,也是放到一个div中,这样便实现了树形结构的显示,至于缩进量则是由这个类别的grade来控制的,每增加一个级别在显示的时候就会给前面放上一张小的透明的图片,因此就有了缩进的效果。 V0.5版本就是完成了商品类别的树形展示。 4.6 V0.6版本 V0.6版本在0.5的基础上完成了商品类别的添加、删除和修改,就是当你在那个商品类别树上点击某个节点的时候在右侧会出现一个页面,它会显示当前节点的名称,并且让你选择操作,有添加子类别、修改此类别和删除此类别及其子类别,如果点击的是全部类别则只会有添加子类别的功能。如图4-16。 图4-16 类别管理页面 当点击添加子类别的时候,就会在当前位置出现一个添加子类别的页面,在上面会显示你在哪个类别下面添加子类别,这里会要求输入类别的名称和描述,名称是必须的,如果不输入会在名称的输入框后面显示一行红字提示说名称不能为空,而描述则不是必须的,详见图4-17。 - 35 - 哈尔滨理工大学学士学位论文 图4-17 添加子类别 当信息都输入完成之后,点击添加就会将这个新类别增加到数据库中,并在左上方提示说添加成功,此时如果刷新左边的类别就会看到这个新类别。 如果点击的是删除此类别及其子类别,则会弹出一个确认框,问是否确认删除,见图4-18。 图4-18 删除商品类别 当点击确定时,就会将这个类别及其所有的子类别一起删除,在执行这样的操作时,是用递归,先找到它最下面子节点,也就是叶子节点,然后将其删除,再删除其同层节点,之后再删除父节点,知道所有的节点都删除完毕,这样还不够,如果这个被删除的节点是其父节点的唯一节点,那么其父节点在这个节点被删除之后也会变成一个叶子节点,所以在删除这些节点之后还需要检查它的父节 - 36 - 哈尔滨理工大学学士学位论文 点是否还有子节点,如果没有子节点了,那就把它的父节点修改为子节点。一次进行了这么多的数据库操作,所以这些操作应当放到一个Transaction(事务)中,这些操作要么都成功,要么都不成功,如果任何一点出现问题都要回滚,具体到编程就是要设置自动提交为FALSE,也就是conn.setAutoCommit(false),等所有的语句都正确无误的执行完成之后再手动提交conn.commit(),如果捕捉到任何异常,就要回滚conn.rollback(),并且要把自动提交再设回到TRUE也就是conn.setAutoCommit(true)。如果成功则会显示删除成功,如果失败则会显示失败。 如果点击的是修改此节点,则会出现修改页面,如图4-19。 图4-19 修改商品类别 在这个页面会把这个商品类别已经有的信息显示上来,这时就可以修改这些信息了,当点击修改时,就会把这些信息保存到数据库中,这个页面会被刷新,并在左上角显示修改成功。 这样V0.6版本的功能也完成了,这个版本里最主要的就是在递归删除时对事务的控制。 4.7 V0.7版本 V0.7版本先是建立了Product类和他的管理类ProductManager类,接着又完成了管理员查看商品,添加、修改和删除商品,接着又完成了商品的搜索。商品信息的显示页面如图4-19所示。 - 37 - 哈尔滨理工大学学士学位论文 图4-19 全部商品 在这里可以会将所有的商品分页列出,显示出它们的详细信息,管理员在这里可以选择添加、删除、修改商品和给商品上传图片(这个版本没有完成图片上传功能),如果选择了添加则转到商品添加页面,如图4-20。 图4-20 添加商品 前面有红*的是必填的,其中商品类别是从数据库中读取出来的树形结构并加上了简单的缩进,当信息都填写无误,点击添加后就会在数据库中加入一条新的商品了,此时这个页面会重新显示,左上角会提示添加成功。 删除商品可以一次删除一个或者多个,给要删除的商品前面打上钩之后点击删除,会弹出一个确认框,如果选确认就会将这些商品删除,此时所有商品的页面就会刷新,那些被删的商品就没有了。 如果选择了一个商品并点击修改,一次只能修改一个,就会进入商品信息修改页面,如图4-21。 - 38 - 哈尔滨理工大学学士学位论文 图4-21 商品信息修改 这里会将商品原来的信息全部显示到页面里,当修改完商品的信息点击修改时,商品在数据库中的信息就会被修改,这是此页会刷新,在页面左上角会显示修改成功。 V0.7还完成了商品的模糊搜索,搜索页面见图4-22。 图4-22 商品搜索 在这里输入任何搜索条件,点击搜索后就会将结果显示出来,搜索是匹配商品的名称或者品牌或者描述,只要任何一条包含这个搜索关键字,就会被查询上来并以分页的形式显示在结果页面中,结果的页面与图4-19一样,但是不能添加商品,只能修改和删除。 这样V0.7版本就完成了,这个版本还是在完成管理员对商品的管理功能,查看、添加、删除和修改商品,以及搜索商品。 - 39 - 哈尔滨理工大学学士学位论文 4.8 V0.8版本 V0.8版本是继续完成管理员为图片上传图片,以及商品在商城首页上的显示,还有用户搜索商品,以及查看商品的详细信息。 为商品上传图片是在商品管理页面选中一个商品,点击上传图片按钮就进入到了图片上传页面,如图4-23。 图4-23 商品图片上传 在这里也会将商品的详细信息罗列出来,此时商品还没有图片,因此在商品图片那里显示的是一个小红叉子,点击浏览就可以选择要上传的图片了,之后点击上传按钮,图片就会被上传到服务器的这个项目的根目录下的一个叫做productPicture的文件夹里,而这张被上传的图片的文件名会被记录到商品的数据库的记录中,之后要显示图片的时候会通过文件名从服务器的那个文件夹列搜索图片并显示。 - 40 - 哈尔滨理工大学学士学位论文 此时,在商场的主页上就能看到这些商品了,如图4-24。 图4-24 商品在商城主页上的展示 这时,如果用户点击一个商品的图片或是它的名称,就会进入到商品详细信息展示页面,如图4-25。 图4-25 商品详细信息 - 41 - 哈尔滨理工大学学士学位论文 在这里,顾客就能看到这个商品的详细信息和100%的图像了,接下来他就可以选择购买此商品或者返回了。 在商城的首页上,还有一个搜索栏以供用户搜索想要的商品,如图4-26。 图4-26 用户搜索商品 在这里输入任何信息,点击搜索之后就会把相关的商品搜索上来,搜索所匹配的是商品的名称或者品牌或者描述,搜索结果见图4-27。 图4-27 商品搜索结果 在这里,顾客同样可以查看这个商品的详细信息,或是直接放入购物车,购物车功能在这个版本里未实现。 这样V0.8版本的功能就全部实现了,先是彻底完成了管理员管理商品的全部功能,这样就让商品有了一个完整的信息,接下来就是怎么在商城的页面上把这些商品显示出来,并分页,我这里在主页上的设定是每页显示6个商品,接着完成了将商品的详细信息显示给顾客的功能,又完成了顾客搜索商品的功能,在下个版本中,就要完成购物车的功能了。 - 42 - 哈尔滨理工大学学士学位论文 4.9 V0.9版本 V0.9版本就是在完成购物车功能,先是建立了ShoppingCart类和CartItem类,还有管理类ShoppingCartManager。ShoppingCart是购物车的主题类,保存着一个购物项的列表,就是一个List,这个List里面装的就是一个个的CartItem,CartItem则保存着每个具体的购物项的信息,ShoppingCartManager则提供一些管理用的方法。 当用户在主页或是搜索结果页面的商品栏里点击我要购买或者在商品详细信息里点击购买按钮时,就会弹出一个新的窗口,上面就是用户选择的那个商品,如图4-28。 图4-28 购物车 此时如果用户点击新的商品,购物车里就会多一项商品,如果顾客点击的是购物车里面已经有的商品,那这个商品的数量就会增加1个。用户也可以手动修 - 43 - 哈尔滨理工大学学士学位论文 改要购买的商品的数量,点击修改之后就会修改了。用户还可以点击没条购物项右边的删除按钮,这样这个购物项就会从购物车中删除了。 通常情况下,购物车可以放在Cookie里或者Session里,在这里我选择放置在Session中,用户对购物车的各种操作其实就是在操作他自己的Session。接下来,用户就能下单给商城了,不过这是下个版本的事情。 4.10 V1.0版本 V1.0版本是商城项目的功能完全实现的版本,这个版本完成之后就实现了这个项目所设计的所有功能和目标。 接着上一个版本的遗留问题,就是要完成用户的下订单功能,用户在自己的购物车里点击下单按钮之后,就会转到订单确认页面,订单确认页面要求必须是注册会员并登陆,因此如果用户还未登陆,需要先登录,之后就会转到订单确认页面,如图4-29。 图4-29 订单确认页面 在这个页面里会将用户所放入购物车的所有物品罗列出来,并且计算出总金额,在这里还会显示用户的送货地址,如果用户想换一个送货地址就可以在这里 - 44 - 哈尔滨理工大学学士学位论文 修改,当用户点击确认下单按钮时,订单就会正式下达给商城了,此时订单的状态是0也就是未处理状态,当订单正式下达之后,原来的购物车也将被清空。接下来就会转到订单成功下达页面,这里会给顾客提示说订单已经成功下达,让用户选择操作,见图4-30。 图4-30 下订单成功页面 这个页面类似于用户登录成功后的页面,用户可以修改自己的个人信息,也可以修改自己的密码,还能继续去查看商品或者是查看自己下的订单。如果用户点击查看我的订单,那就转到用户查看订单页面,如图4-31。 图4-31 用户查看自己的订单 - 45 - 哈尔滨理工大学学士学位论文 现在编程有转向管理员方向,既然用户已经下了订单了,那管理员就应该能看到并且处理它们。在管理管理订单这里,管理员可以查看所有订单或者查看未处理订单,当管理员点击订单管理下面的未处理订单按钮时,就会在工作区列出所有还未处理的订单,如图4-32。 图4-32 未处理订单 在这个页面里,会把所有未处理的订单罗列出来,每页显示10条,如果当前页已经是第一页,那首页和上一页的按钮将会变灰不可用,如果已经是最后一页了,那下一页和最后一页的按钮就会变灰不可用,如果只有一页,那这些分页按钮将都不可用,如果一条记录都没有,像修改、删除、上传图片和处理订单这些按钮也将变灰不可用,这点在商城的后台管理系统中所有有分页的地方都适用。 如果管理员点击了每条记录后面那个明细之后,就会将这个订单的详细购物项罗列出来显示到订单详细页面上,如图4-33。 - 46 - 哈尔滨理工大学学士学位论文 图4-33 查看订单明细 在这个页面里,属于那个订单的所有订单项都会被详细的列出来,商品是什么,单价多少,买了几个,每项的小计金额。这里只有一个按钮,就是返回,当点击这个按钮时就返回刚才的未处理订单页面。 当管理员选择一个订单,也只能选择一个,点击订单处理按钮,就会转到订单处理页面,如图4-34。 图4-34 订单处理 在这个页面也会将订单的详细信息列出来,因为这个商城系统并没有涉及与银行系统的连接,所以处理订单也就是简单的改一下订单的状态。 当管理员选择了一个订单的状态,已处理或者是已作废时,再点击处理订单就会将这个订单的状态改为所选的那个状态,之后会继续转到未处理订单页面以让管理员继续处理,直到全部处理完成。 当管理员点击的是订单管理下面的全部订单按钮时,就会将所有的订单都列 - 47 - 哈尔滨理工大学学士学位论文 出来,在这里管理员能查看它们的详细信息或者删除它们,但是不可以处理订单。一个系统的后台总是要求安全性高点,因此这里必须加入安全性的验证,对于这个后台管理系统,我再次用了Filter,因为所有的后台管理的东西都放在了admin文件夹下,因此我这个Filter就配置成了,只要访问admin文件夹下的任何页面都会被Filter过滤,在这个Filter里我就是在检查管理员是否已经登录,也就是检查Session,如果没有登录,则打回到登录页面要求其登录,否则就放行。 有登录必然要有注销,在后台管理页面的工作区上面就有一个注销链接,当点击它的时候,就会将管理员登录的放到Session中的信息清除掉,就完成了注销,见图4-35。 图4-35 管理员注销 既然管理员有注销功能,那用户当然不能落下,在用户的操作页面的右上 - 48 - 哈尔滨理工大学学士学位论文 方,总是有三个链接,一个是返回主页,一个是用户自服务,另一个就是注销,见图4-36。 图4-36 用户的选择区域 返回首页这功能我就不介绍了,用户子服务嘛,点一下就是打开用户登录完成之后那窗口,让用户选择干什么,注销登录点一下之后就会把这个用户的Session清空,也就是完成了注销,见图4-37。 图4-37 用户注销页面 最后的最后,我还是弄了点其他的东西,就是错误页面,这可以让网站显得 - 49 - 哈尔滨理工大学学士学位论文 更加的友好,而不是突然蹦出来个白花花的错误页面,上面写了一大堆英文,因此我做了一个404错误页面,一个500错误页面,其中404页面的素材是从网上找到一段flash,很好玩,很搞笑,只有亲自看过之后才能体会出来它做的非常好,我下面贴俩张图吧,见图4-38和图4-39。 图4-38 搞笑的404页面 图4-39 搞笑的404页面 500页面是自己找的一张图片贴上去的,是一只可爱的猫咪,如图4-40。 - 50 - 哈尔滨理工大学学士学位论文 图4-40 500错误页面 最后这个版本也完成了,这样一个比较完整的网上商城系统就都做完了,这个系统虽然不算大,也不能说小,做的时候碰到的问题还是很多的,收获也颇丰啊。 - 51 - 哈尔滨理工大学学士学位论文 4.11 本章小结 这章主要就是对各个版本完成时进行一个一些功能性的测试,看看其是否达到了设计要求,还有什么问题没有解决,还有哪些可以改进的问题,因为采用的是螺旋递增式的开发,这样在每个小版本开发完成之后立即就进行测试,有利于提早发现问题,并将其解决,对后期开发的影响也会降到最低,而且在测试的过程之中可能就会发现更好的解决方法或者使用上的更加人性化。 整个系统完成之后,我又对整个系统进行了整体的测试,看看各个模块之间是否还有问题,在测试的过程之中还发现一些能让网站更加人性化的方法,于是又增加、修改了一部分功能,比如加入404页面和500页面。最后,整个系统的测试结果达到了设计要求。 - 52 - 哈尔滨理工大学学士学位论文 结 论 本文较完整地讨论了一个网上商城系统的分析、设计与实现,使用了Java Web开发的一些常用的方法和技巧,比如前端的HTML、CSS、JavaScript服务器端的JSP、Servlet、Filter等,以及MySQL数据库,并运用了一些开源的第三方组件,通过对这些技术的综合应用,最终实现了一个网上商城系统的主要功能。用户方面的注册、登录、修改个人信息,修改个人密码,查看商品、搜索商品、将商品放入购物车、下订单、查看自己的订单,和注销。商城后台管理方面实现了查看商城的注册会员,修改和删除会员信息,查看、添加、删除和修改商品类别的信息,查看、添加、删除和修改商品的信息,查看、处理和删除订单、管理员自身的登录和修改密码以及注销。因此,针对如何使用Java作为主要开发语言来实现一个网上商城系统的问题,本文的主要工作如下: 1(研究了如何来分析一个网上商城系统的构成和一般流程。 2(建立了一种站在使用者角度的分析方法,来对一个网上商城进行分析。 3(利用螺旋递增开发模式,实现了一种比较直观易懂的开发途径。 4(基于Filter在面向切面编程方面的广泛应用,实现了用Filter来处理一些 通用流程的方式。 综上所述本文对如何对一个系统进行分析和设计的问题提出了一些针对性的方法,今后的工作还应该在如何更好的使用面向对象的分析和设计方法来更好的解决软件编程中的问题上不断的努力。 - 53 - 哈尔滨理工大学学士学位论文 致 谢 首先,衷心感谢我的导师老师,在工作非常繁忙的情况下,他自始至终给予 我非常大的帮助,在此谢谢老师~ - 54 - 哈尔滨理工大学学士学位论文 参考文献 1 陈锡年(网上商城务实(机械工业出版社,2009:12~26 2 David J.Barnes(Object First with Java(Third Edition)(机械工业出版社, 2008:130~135 3 罗玉玲(J2EE应用开发详解(电子工业出版社,2009:167~199 4 胡艳洁(HTML标准教程(中国青年出版社,2004:170~174 5 王萍萍(JavaScript 应用开发技术详解(科学出版社,2008:179~180 6 李刚(疯狂Ajax讲义(电子工业出版社,2009:147~152 7 孙鑫(Servlet/JSP深入详解(电子工业出版社,2008:233~260 8 郑阿奇(MySQL实用教程(电子工业出版社,2009:34~35 9 封超,晁阳(Tomcat与Java Web开发技术详解(清华大学出版社,2008: 53~74 10 孙卫琴(Tomcat与Java Web开发技术详解(第2版)(电子工业出版社, 2009:38~41 11 张银鹤(XML实践教程(清华大学出版社,2007:63~91 12 郑阿奇(Eclipse实用教程(电子工业出版社,2009:82~102 13 王军(DreamweaverMX2004网页设计标准教材(电子工业出版社, 2007:96~134 14 Nicholas C.Zakas(Professional JavaScript for Web Developers(人民邮电出版 社,2006:137~161 15 Bruce Eckel(Tinking in Java (Fourth Edition)(机械工业出版社,2007: 238~286 - 55 - 哈尔滨理工大学学士学位论文 附 录 附录A 英文原文 Introduction to Objects “We cut nature up, organize it into concepts, and ascribe significances as we do, largely because we are parties to an agreement that holds throughout our speech community and is codified in the patterns of our language … we cannot talk at all except by subscribing to the organization and classification of data which the agreement decrees.” Benjamin Lee Whorf (1897-1941) The genesis of the computer revolution was in a machine. The genesis of our programming languages thus tends to look like that machine. But computers are not so much machines as they are mind amplification tools (“bicycles for the mind,” as Steve Jobs is fond of saying) and a different kind of expressive medium. As a result, the tools are beginning to look less like machines and more like parts of our minds, and also like other forms of expression such as writing, painting, sculpture, animation, and filmmaking. Object-oriented programming (OOP) is part of this movement toward using the computer as an expressive medium. This chapter will introduce you to the basic concepts of OOP, including an overview of development methods. This chapter, and this book, assumes that you have some programming experience, although not necessarily in C. If you think you need more preparation in programming before tackling this book, you should work through the Thinking in C multimedia seminar, downloadable from www.MindView.net. This chapter is background and supplementary material. Many people do not feel comfortable wading into object-oriented programming without understanding the big picture first. Thus, there are many concepts that are introduced here to give you a solid overview of OOP. However, other people may not get the big picture concepts until they’ve seen some of the mechanics first; these people may become bogged down and lost without some code to get their hands on. If you’re part of this latter group and are eager to get to the specifics of the language, feel free to jump past this chapter— skipping it at this point will not prevent you from writing programs or learning the - 56 - 哈尔滨理工大学学士学位论文 language. However, you will want to come back here eventually to fill in your knowledge so you can understand why objects are important and how to design with them. The progress of abstraction 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 implementing that solution, such as a computer) and the model of the problem that is actually being solved (in the 16 Thinking in Java Bruce Eckel problem space, which is the place where the problem exists, such as a business). 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 may be 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 - 57 - 哈尔滨理工大学学士学位论文 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.1 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: 1.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. 2.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. 3.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. 4.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?” 5.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. - 58 - 哈尔滨理工大学学士学位论文 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. An object has an interface 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 numerous 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 - 59 - 哈尔滨理工大学学士学位论文 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 [15]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 needs to 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. A simple example might be a representation of a light bulb: Figure A,1 LIGHT Light it = new Light(); it.on(); The interface determines the requests that 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 - 60 - 哈尔滨理工大学学士学位论文 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 it, 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” (it) 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, as in this case. If you’re interested only in the class name, then the bottom portion doesn’t need to be shown, either. 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 - 61 - 哈尔滨理工大学学士学位论文 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 can 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. This not only allows the discovery of objects that might be purchased (the printer interface object), but it also produces new objects that might be reused somewhere else (the catalog of check layouts). Treating objects as service providers is a great simplifying tool. This is 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. - 62 - 哈尔滨理工大学学士学位论文 附录B 英文译文 对象导论 “我们之所以将自然界分解,组织成各种概念,并按其含义分类,主要是因为我们是整个口语交流社会共同遵守的协定的参与者,这个协定以语言的形式固定下来,除非赞成这个协定中规定的有关语言信息的组织和分类,否则我们根本无法交谈。” --Benjamin Lee Whorf (1897~1941) 计算机革命起源于机器,因此,编程语言的产生也始于对机器的模仿。但是,计算机并非只是机器那么简单。计算机是头脑延伸的工具(就像Steve Jobs常喜欢说的“头脑的自行车一样” ),同时还是一种不同类型的表达媒体。因此,这种工具看起来已经越来越不像机器,而更像我们头脑的一部分,以及一种如写作、绘画、雕刻、动画、电影等一样的表达形式。面向对象程序设计(Object-oriented Programming,OOP)便是这种以计算机作为表达媒体的大趋势中的组成部分。 本章将向读者介绍包括开发方法概述在内的OOP的基本概念。本章,乃至本 关于书的成语关于读书的排比句社区图书漂流公约怎么写关于读书的小报汉书pdf 中,都假设读者已经具备了某些编程经验(当然不一定是C的)。如果读者认为在阅读本书之前还需要在程序设计方面多做些准备,那么就应该去研读可以从www.MindView.net网站上下载的《C编程思想》(Thinking in C)的多媒体资料。 本章介绍的是背景性的和补充性的材料。许多人在没有了解面向对象程序设计的全貌之前,感觉无法轻松自在地从事此类编程。因此,此处将引入许多概念,以期帮助读者扎实地了解OOP。然而,还有些人可能在看到具体结构之前,无法了解面向对象程序设计的全貌,这些人如果没有代码在手,就会陷于困境并最终迷失方向。如果你属于后面这个群体,并且渴望尽快获取Java语言的细节,那么可以先越过本章——在此处越过本章并不会妨碍你编写程序和学习语言。但是,你最终还是要回到本章来补充所学知识,这样才能够了解到对象的重要性,以及怎样使用对象进行设计。 抽象过程 所有编程语言都提供抽象机制。可以认为,人们所能够解决的问题的复杂性直接取决于抽象的类型和质量。所谓的“类型”是指“所抽象的是什么,”汇编语言是对底层机器的轻微抽象。接着出现的许多所谓“命令式”语言(如FORTRAN、BASIC、C等)都是对汇编语言的抽象。这些语言在汇编语言基础上有了大幅的改进,但是它们所作的主要抽象仍要求在解决问题时要基于计算机 - 63 - 哈尔滨理工大学学士学位论文 的结构,而不是基于所要解决的问题的结构来考虑。程序员必须建立起在机器模型(位于“解空间”内,这是你对问题建模的地方,例如计算机)和实际待解问题的模型(位于“问题空间”内,这是问题存在的地方,例如一项业务)之间的关联。建立这种映射是费力的,而且这不属于编程语言所固有的功能,这使得程序难以编写,并且维护代价高昂,同时也产生了作为副产物的整个“编程方法”行业。 另一种对机器建模的方式就是只针对待解问题建模。早期的编程语言,如LISP和APL,都选择考虑世界的某些特定视图(分别对应于“所有问题最终都是列表”或者“所有问题都是算法形式的” )。 PROLOG则将所有问题都转换成决策链。此外还产生了基于约束条件编程的语言和专门通过对图形符号操作来实现编程的语言(后者被证明限制性过强)。这些方式对于它们所要解决的特定类型的问题都是不错的解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,但是一旦超出其特定领域,它们就力不从心了。 面向对象方式通过向程序员提供表示问题空间中的元素的工具而更进了一步。这种表示方式非常通用,使得程序员不会受限于任何特定类型的问题。我们将问题空间中的元素及其在解空间中的表示称为“对象” 。(你还需要一些无法类比为问题空间元素的对象)。这种思想的实质是:程序可以通过添加新类型的对象使自身适用干某个特定问题。因此,当你在阅读描述解决方案的代码的同时,也是在阅读问题的表述。相比以前我们所使用的语言,这是一种更灵活和更强有力的语言抽象。所以,OOP允许根据问题来描述问题,而不是根据运行解决方案的计算机来描述问题。但是它仍然与计算机有联系:每个对象看起来都有点像一台微型计算机——它具有状态,还具有操作,用户可以要求对象执行这些操作。如果要对现实世界中的对象作类比,那么说它们都具有特性和行为似乎不错。 Alan Kay曾经总结了第一个成功的面向对象语言、同时也是Java所基于的语言之一的Smalltalk的五个基本特性,这鉴特性表现了一种纯粹的面向对象程序设计方式: 1(万物皆为对象。将对象视为奇特的变量,它可以存储数据,除此之外, 你还可以要求它在自身上执行操作。理论上讲,你可以抽取待求解问题 的任何概念化构件(狗、建筑物、服务等),将其表示为程序中的对 象。 2(程序是对象的集合,它们通过发送消息来告知彼此所要做的。要想请求 一个对象,就必须对该对象发送一条消息。更具体地说,可以把消息想 - 64 - 哈尔滨理工大学学士学位论文 像为对某个特定对象的方法的调用请求。 3(每个对象都有自己的由其他对象所构成的存储。换句话说,可以通过创 建包含现有对象的包的方式来创建新类型的对象。因此,可以在程序中 构建复杂的体系,同时将其复杂性隐藏在对象的简单性背后。 4(每个对象都拥有其类型。按照通用的说法,“每个对象都是某个类 (class)的一个实例(instance)” ,这里“类”就是“类型”的同义 词。每个类最重要的区别于其他类的特征就是“可以发送什么样的消息 给它” 。 5(某一特定类型的所有对象都可以接收同样的消息。这是一句意味深长的 表述,你在稍后便会看到。因为“圆形”类型的对象同时也是“几何 形”类型的对象,所以一个“圆形”对象必定能够接受发送给“几何 形”对象的消息。这意味着可以编写与“几何形”交互并自动处理所有 与几何形性质相关的事物的代码。这种可替代性(substitutability)是 OOP中最强有力的概念之一。 Booch对对象提出了一个更加简洁的描述:对象具有状态、行为和标识。这意味着每一个对象都可以拥有内部数据(它们给出了该对象的状态)和方法(它们产生行为),并且每一个对象都可以唯一地与其他对象区分开来,具体说来,就是每一个对象在内存中都有一个唯一的地址。 每个对象都有一个接口 亚里士多德大概是第一个深入研究类型(type)的哲学家,他曾提出过鱼类和鸟类这样的概念。所有的对象都是唯一的,但同时也是具有相同的特性和行为的对象所归属的类的一部分。这种思想被直接应用于第一个面向对象语言Simula-67,它在程序中使用基本关键字class来引入新的类型。 Simula,就像其名字一样,是为了开发诸如经典的“银行出纳员问题”(bank teller problem)这样的仿真程序而创建的。在银行出纳员问题中,有出纳、客户,账户、交易和货币单位等许多“对象” 。在程序执行期间具有不同的状态而其他方面都相似的对象会被分组到对象的类中,这就是关键字class的由来。创建抽象数据类型(类)是面向对象程序设计的基本概念之一。抽象数据类型的运行方式与内置(built-in)类型几乎完全一致:你可以创建某一类型的变量(按照面向对象的说法,称其为对象或实例),然后操作这些变最(称其为发送消息或请求;发送消息,对象就知道要做什么)。每个类的成员或元素都具有某种共性:每个账户都有结余金额,每个出纳都可以处理存款请求等。同时,每个成员都有其自身的状态:每个账户都有不同的结余金额,每个出纳都有自己的 - 65 - 哈尔滨理工大学学士学位论文 姓名。因此,出纳、客户、账户、交易等都可以在计算机程序中被表示成唯一的实体口这些实体就是对象,每一个对象都属于定义了特性和行为的某个特定的类。 所以,尽管我们在面向对象程序设计中实际上进行的是创建新的数据类型,但事实上所有的面向对象程序设计语言都使用class这个关键词来表示数据类型。当看到类型一词时,可将其作为类来考虑,反之亦然。 因为类描述了具有相同特性(数据元素)和行为(功能)的对象集合,所以一个类实际上就是一个数据类型,例如所有浮点型数字具有相同的特性和行为集合。二者的差异在于,程序员通过定义类来适应问题,而不再被迫只能使用现有的用来表示机器中的存储单元的数据类型。可以根据需求,通过添加新的数据类型来扩展编程语言。编程系统欣然接受新的类,并且像对待内置类型一样地照管它们和进行类型检查。 面向对象方法并不是仅局限于构建仿真程序。无论你是否赞成以下观点,即任何程序都是你所设计的系统的一种仿真,面向对象技术的应用确实可以将大量的问题很容易地降解为一个简单的解决方案。 一旦类被建立,就可以随心所欲地创建类的任意个对象,然后去操作它们,就像它们是存在于你的待求解问题中的元素一样。事实上,面向对象程序设计的挑战之一,就是在问题空间的元素和解空间的对象之间创建一对一的映射。 但是,怎样才能获得有用的对象呢,必须有某种方式产生对对象的请求,便对象完成各种任务,如完成一笔交易、在屏幕上画图、打开开关等等。每个对象都只能满足某些请求,这些请求由对象的接口(interface)所定义,决定接口的便是类型。以电灯泡为例来做一个简单的比喻(如下图所示): 图B-1 灯泡 Light it = new Light(); it.on(); - 66 - 哈尔滨理工大学学士学位论文 接口确定了对某一特定对象所能发出的请求。但是,在程序中必须有满足这些请求的代码。这些代码与隐藏的数据一起构成了实现。从过程型编程的观点来看,这并不太复杂。在类型中,每一个可能的请求都有一个方法与之相关联,当向对象发送请求时,与之相关联的方法就会被调用。此过程通常被概括为:向某个对象“发送消息”(产生请求),这个对象便知道此消息的目的,然后执行对应的程序代码。 上例中,类型/类的名称是Light,特定的Light对象的名称是It,可以向Light对象发出的请求是:打开它、关闭它、将它调亮、将它调暗。你以下列方式创建了一个Light对象:定义这个对象的“引用”(it),然后调用new方法来创建该类型的新对象。为了向对象发送消息,需要声明对象的名称,并以圆点符号连接一个消息请求。从预定义类的用户观点来看,这些差不多就是用对象来进行设计的全部。 前面的图是UML(Unified Modeling Language,统一建模语言)形式的图,每个类都用一个方框表示,类名在方框的顶部,你所关心的任何数据成员都描述在方框的中间部分,方法(隶属于此对象的、用来接收你发给此对象的消息的函数)在方框的底部。通常,只有类名和公共方法被示于UML设计图中,因此,方框的中部就像本例一样并未给出。如果只对类型感兴趣,那么方框的底部甚至也不需要给出。 每个对象都提供服务 当正在试图开发或理解一个程序设计时,最好的方法之一就是将对象想像为“服务提供者” 。程序本身将向用户提供服务,它将通过调用其他对象提供的服务来实现这一目的。你的目标就是去创建(或者最好是在现有代码库中寻找)能够提供理想的服务来解决问题的一系列对象。 着手从事这件事的一种方式就是问一下自己:“如果我可以将问题从表象中抽取出来,那么什么样的对象可以马上解决我的问题呢,”例如,假设你正在刨建一个簿记系统,那么可以想像,系统应该具有某些包括了预定义的簿记输入屏幕的对象,一个执行簿记计算的对象集合,以及一个处理在不同的打印机上打印支票和开发票的对象。也许上述对象中的某些已经存在了,但是对于那些并不存在的对象,它们看起来像什么样子,它们能够提供哪些服务,它们需要哪些对象才能履行它们的义务,如果持续这样做,那么最终你会说“那个对象看起来很简单,可以坐下来写代码了” ,或者会说“我肯定那个对象已经存在了” 。这是将问题分解为对象集合的一种合理方式。 将对象看作是服务提供者还有一个附带的好处:它有助于提高对象的内聚 - 67 - 哈尔滨理工大学学士学位论文 性。高内聚是软件设计的基本质量要求之一:这意味着一个软件构件(例如一个对象,当然它也有可能是指一个方法或一个对象库)的各个方面“组合”得很好。人们在设计对象时所面临的一个问题是,将过多的功能都塞在一个对象中。例如,在检查打印模式的模块中,你可以这样设计一个对象,让它了解所有的格式和打印技术。你可能会发现,这些功能对于一个对象来说太多了,你需要的是三个甚至更多个对象,其中,一个对象可以是所有可能的支票排版的目录,它可以被用来查询有关如何打印一张支票的信息,另一个对象(或对象集含)可以是一个通用的打印接口,它知道有关所有不同类型的打印机的信息(但是不包含任何有关簿记的内容,它更应该是一个需要购买而不是自己编写的对象)。第三个对象通过调用另外两个对象的服务来完成打印任务。这样,每个对象都有一个它所能提供服务的内聚的集合。在良好的面向对象设计中,每个对象都可以很好地完成一项任务,但是它并不试图做更多的事。就像在这里看到的,不仅允许通过购买获得某些对象(打印机接口对象),而且还可以创建能够在别处复用的新对象(支票排版目录对象)。 将对象作为服务提供者看待是一件伟大的简化工具,这不仅在设计过程中非常有用,而且当其他人试图理解你的代码或重用某个对象时,如果他们看出了这个对象所能提供的服务的价值,它会使调整对象以适应其设计的过程变得简单得多。 - 68 -
本文档为【java毕业设计--用Java web开发的网上商城系统】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_808969
暂无简介~
格式:doc
大小:619KB
软件:Word
页数:87
分类:企业经营
上传时间:2017-09-05
浏览量:61