java面向对象编程思考过程

上传人:xy****7 文档编号:42748066 上传时间:2018-06-03 格式:DOC 页数:6 大小:33.50KB
返回 下载 相关 举报
java面向对象编程思考过程_第1页
第1页 / 共6页
java面向对象编程思考过程_第2页
第2页 / 共6页
java面向对象编程思考过程_第3页
第3页 / 共6页
java面向对象编程思考过程_第4页
第4页 / 共6页
java面向对象编程思考过程_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《java面向对象编程思考过程》由会员分享,可在线阅读,更多相关《java面向对象编程思考过程(6页珍藏版)》请在金锄头文库上搜索。

1、 我是从学习 Java 编程开始接触 OOP(面向对象编程),刚开始使用 Java 编写程序的时候感 觉很别扭,因为我早以习惯用 C 来编写程序,很欣赏 C 的简洁性和高效性,喜欢 C 简练而表 达能力丰富的风格,特别忍受不了 Java 运行起来慢吞吞的速度,相对冗长的代码,而且一 个很简单的事情,要写好多类,一个类调用一个类,心里的抵触情绪很强。我对 Java 的面向对象的特性琢磨良久,自认为有所领悟,也开始有意识的运用 OOP 风格来写程序,然而还是经常会觉得不知道应该怎样提炼类,面对一个具体的问题的时候, 会觉得脑子里千头万绪的,不知道怎么下手,一不小心,又会回到原来的思路上去。举个例子

2、,要发广告邮件,广告邮件列表存在数据库里面。倘若用 C 来写的话,一般 会这样思考,先把邮件内容读入,然后连接数据库,循环取邮件地址,调用本机的 qmail 的 sendmail 命令发送。然后考虑用 Java 来实现,既然是 OOP,就不能什么代码都塞到 main 过程里面,于是 就设计了三个类:一个类是负责读取数据库,取邮件地址,调用 qmail 的 sendmail 命令发送;一个类是读邮件内容,MIME 编码成 HTML 格式的,再加上邮件头;一个主类负责从命令读参数,处理命令行参数,调用发 email 的类。把一件工作按照功能划分为 3 个模块分别处理,每个类完成一件模块任务。仔细的

3、分析一下,就会发现这样的设计完全是从程序员实现程序功能的角度来设计的, 或者说,设计类的时候,是自低向上的,从机器的角度到现实世界的角度来分析问题的。因 此在设计的时候,就已经把程序编程实现的细节都考虑进去了,企图从底层实现程序这样的 出发点来达到满足现实世界的软件需求的目标。这样的分析方法其实是不适用于 Java 这样面向对象的编程语言,因为,如果改用 C 语言,封装两个 C 函数,都会比 Java 实现起来轻松的多,逻辑上也清楚的多。我觉得面向对象的精髓在于考虑问题的思路是从现实世界的人类思维习惯出发的,只 要领会了这一点,就领会了面向对象的思维方法。举一个非常简单的例子:假使现在需要写一

4、个网页计数器,客户访问一次页面,网页 计数器加 1,计数器是这样来访问的http:/hostname/count.cgi?id=xxx后台有一个数据库表,保存每个 id(一个 id 对应一个被统计访问次数的页面)的计 数器当前值,请求页面一次,对应 id 的计数器的字段加 1(这里我们忽略并发更新数据库表, 出现的表锁定的问题)。如果按照一般从程序实现的角度来分析,我们会这样考虑:首先是从 HTTP GET 请求取到 id,然后按照 id 查数据库表,获得某 id 对应的访问计数值,然后加1,更新数据库,最后向页面显示访问计数。现在假设一个没有程序设计经验的人,他会怎样来思考这个问题的呢?他会

5、提出什么 样的需求呢?他很可能会这样想:我需要有一个计数器,这个计数器应该有这样的功能,刷新一次页面,访问量就会加 1,另外最好还有一个计数器清 0 的功能,当然计数器如果有一个可以设为任意值的功能的 话,我就可以作弊了。做为一个没有程序设计经验的人来说,他完全不会想到对数据库应该如何操作,对于 HTTP 变量该如何传递,他考虑问题的角度就是我有什么需求,我的业务逻辑是什么,软件 应该有什么功能。按照这样的思路(请注意,他的思路其实就是我们平时在生活中习惯的思维方式),我 们知道需要有一个计数器类 Counter,有一个必须的和两个可选的方法:getCount() / 取计数器值方法reset

6、Counter() / 计数器清 0 方法setCount() / 设计数器为相应的值方法把 Counter 类完整的定义如下:public class Counter public int getCount(int id) public void resetCounter(int id) public void setCount(int id, int currentCount) 解决问题的框架已经有了,来看一下如何使用 Counter。 在 count.cgi 里面调用 Counter 来计数,程序片断如下:/ 这里从 HTTP 环境里面取 id 值.Counter myCounter =

7、 new Counter(); / 获得计数器int currentCount = myCounter.getCount(id); / 从计数器中取计数/ 这里向客户浏览器输出.程序的框架全都写好了,剩下的就是实现 Counter 类方法里面具体的代码了,此时才 去考虑具体的程序语言实现的细节,比如,在 getCount()方法里面访问数据库,更新计数 值。从上面的例子中看到,面向对象的思维方法其实就是我们在现实生活中习惯的思维方 式,是从人类考虑问题的角度出发,把人类解决问题的思维方式逐步翻译成程序能够理解的思维方式的过程,在这个翻译的过程中,软件也就逐步被设计好了。在运用面向对象的思维方法

8、进行软件设计的过程中,最容易犯的错误就是开始分析的 时候,就想到了程序代码实现的细节,因此封装的类完全是基于程序实现逻辑,而不是基于 解决问题的业务逻辑。学习 JDBC 编程的经典错误问法是:“我怎样封装对数据库的 select 操作?”面向对象的设计是基于解决业务问题的设计,而不是基于具体编程技术的设计。我不 会去封装 select 语句的,我只封装解决问题的业务逻辑,对数据库的读取是在业务逻辑的 编码实现阶段才去考虑的问题。回过头看上面那个发广告邮件的例子,应该如何应用面向对象的思维方法呢?对于一个邮件来说,有邮件头,邮件体,和邮件地址这三个属性,发送邮件,需要一 个发送的方法,另外还需要

9、一个能把所有邮件地址列出来的方法。所以应该如下设计:类 JunkMail属性:headbodyaddress方法:sendMail() / 发送邮件listAllMail() / 列邮件地址用 Java 来表示:public class JunkMail private String head;private String body;private String address;public JunkMain() / 默认的类构造器/ 从外部配置文件读邮件头和邮件体this.head=.;this.body=.;public static boolean sendMail(String add

10、ress) / 调用 qmail,发送 emailpublic static Collection listAllMail() / 访问数据库,返回一个邮件地址集合当把 JunkMail 设计好了以后,再调用 JunkMail 类完成邮件的发送,将是非常轻松的 事情。如果说传统的面向过程的编程是符合机器运行指令的流程的话,那么面向对象的思维 方法就是符合现实生活中人类解决问题的思维过程。在面向对象的软件分析和设计的时候,要提醒自己,不要一上来就去想程序代码的实 现,应该抛开具体编程语言的束缚,集中精力分析我们要实现的软件的业务逻辑,分析软件 的业务流程,思考应该如何去描述和实现软件的业务。毕竟

11、软件只是一个载体,业务才是我 们真正要实现的目标。但是在设计过程中,心里却往往在担心,如果我完全不去考虑程序代码的实现的话, 那么我怎么知道我的设计一定合理呢?我怎么知道我设计的类、接口一定可以实现呢?所以 经常可以看到的现象就是:在设计过程中,虽然知道不能过早考虑代码实现,但是每设计一个类,一个接口,心 里都要不知不觉的用自己熟悉的编程语言大概的评估一下,看看能否编出来,因此,一不小 心,就会又回到按照程序功能实现的思路进行设计的老路上去了。举个例子来说明,在做 Web 程序设计的时候,经常要遇到分页显示数据的情况。比如 说需要把系统中所有的用户都列出来这样的功能。假设使用 User 类来表

12、示用户,增加用户 addUser(),删除用户 deleteUser(),查询所有用户 listUsers()方法。而数据库中有一个 user 表,一条记录是一个用户的信息。下面考虑一下 User 类的方法的实现:addUser()和 deleteUser()方法都好实现,就是对数据库增加记录和删除记录。对于 listUsers()方法,其实就是对 user 表的 select,取出一个记录集。但是该怎么从 listUsers()方法中得到所有用户的列表呢?一个方法调用的返回值只有一个,没有多个,所以很多情况下采用的办法就是返回值 定义为集合类型,比如 Vector。这样就可以在 listUs

13、ers()方法的具体代码实现的时候,从 数据库依次取出一个个记录,插入到 Vector 里面来。在主程序里面,调用 listUsers()方 法可以返回一个 Vector,然后再对 Vector 遍历操作,就可以得到用户列表了。public class User public static void addUser(.) / 数据库 insert 一条记录public static void deleteUser(.) / 数据库 delete 一条记录public Vector listUsers(.) / 数据库 select 结果放到一个集合里面这样的设计基本合理,但是仍然有点小问题。因

14、为在设计的时候,就考虑到了用 Java 的集合类 Vector 来实现对不定长数据集的存放,因而违反了面向对象设计的一个原则: 在设计的时候不应过早的考虑具体程序语言的实现。所以必须用抽象的方法,和具体实现无 关的方法来表达业务逻辑。我们知道,通常对具有集合特征的数据结构进行遍历通常可以使用 next 和 hasNext 方法,next 实现取下一个用户,hasNext 判断是否还有元素。 因此我们定义一个接口 Iterator,这个接口中定义两个方法 next 和 hasNext:public interface Iterator public boolean hasNext() publi

15、c Object next() 而 User 类的 listUses 方法返回值改为 Iterator 接口的实现类:public class User .public Iterator listUsers() .这样就把 User 类的设计和具体的实现方法分离开了,因为此时任何实现了 next()和 hasNext()方法的类都可以做为 listUsers 的返回值,都可以被用来表达“用户列表” ,而不 仅仅可以使用 Vector 而已。比如,我可以用 ArrayList 来表达用户列表,因为 ArrayList 也实现了 Iterator,当然我也可以自己专门写一个类来存放用户列表,只要实

16、现 next()和 hasNext()方法就行了。这样在具体的编写代码的时候,程序员具有了最大的灵活性,可以根据具体的情况, 采用不同的编程方法来存放用户列表。特别是降低了程序的耦合度,提高了程序的可移植性。 对于上面那个 JunkMail 的 listAllMail()方法也同样应该改为接口类型。然后,在主程序里面就这样来使用 User 类的 listUsers 方法:User myUser = new User();Iterator iterator = myUser.listUsers();while (iterator.hasNext() iterator.next();这样就可以完全不用考虑程序代码实现了,从高层次上把功能抽象出来,定义成为接 口,同时又可以把系统设计的很合理,完全根据业务的需求来进行设计。结语通过上面的几个例子的设计说明,使用面向对象的思维方法,其实是一个把业务逻辑 从具体的编程技术当中抽象出来的过程,而这个抽象的

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号