- 浏览: 576402 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
a1641693970:
还不错,学习了
BeanUtils使用总结(二)LazyDynaBean -
zjfshowtime:
很好的办法,学习了。
ORA-28001: the password has expired -
ya654277yo:
哦,多谢分享
Apache整合Tomcat后get方式提交中文乱码问题解决 -
foolkeeper:
nice !!
jvm内存参数设定 -
tracy821:
谢谢了,找了好久才找到
关于Spring 声明式事务处理时,throws exception不回滚的问题
三种修改现有代码提高其可重用性的方法,它们分别是:改写类的实例方法,把参数类型改成接口,选择最简单的参数接口类型。
措施一:改写类的实例方法
通过类继承实现代码重用不是精确的代码重用技术,因此它并不是最理想的代码重用机制。换句话说,如果不继承整个类的所有方法和数据成员,我们无法重用该类里面的单个方法。继承总是带来一些多余的方法和数据成员,它们总是使得重用类里面某个方法的代码复杂化。另外,派生类对父类的依赖关系也使得代码进一步复杂化:对父类的改动可能影响子类;修改父类或者子类中的任意一个类时,我们很难记得哪一个方法被子类覆盖、哪一个方法没有被子类覆盖;最后,子类中的覆盖方法是否要调用父类中的对应方法有时并不显而易见。
任何方法,只要它执行的是某个单一概念的任务,就其本身而言,它就应该是首选的可重用代码。为了重用这种代码,我们必须回归到面向过程的编程模式,把类的实例方法移出成为全局性的过程。为了提高这种过程的可重用性,过程代码应该象静态工具方法一样编写:它只能使用自己的输入参数,只能调用其他全局性的过程,不能使用任何非局部的变量。这种对外部依赖关系的限制简化了过程的应用,使得过程能够方便地用于任何地方。当然,由于这种组织方式总是使得代码具有更清晰的结构,即使是不考虑重用性的代码也同样能够从中获益。
在Java中,方法不能脱离类而单独存在。为此,我们可以把相关的过程组织成为独立的类,并把这些过程定义为公用静态方法。
例如,对于下面这个类:
class Polygon { . . public int getPerimeter() {...} public boolean isConvex() {...} public boolean containsPoint(Point p) {...} . . } |
我们可以把它改写成:
class Polygon { . . public int getPerimeter() {return pPolygon.computePerimeter(this);} public boolean isConvex() {return pPolygon.isConvex(this);} public boolean containsPoint(Point p) {return pPolygon.containsPoint(this, p);} . } |
其中,pPolygon是:
class pPolygon { static public int computePerimeter(Polygon polygon) {...} static public boolean isConvex(Polygon polygon) {...} static public boolean containsPoint(Polygon polygon, Point p) {...} } |
从类的名字pPolygon可以看出,该类所封装的过程主要与Polygon类型的对象有关。名字前面的p表示该类的唯一目的是组织公用静态过程。在Java中,类的名字以小写字母开头是一种非标准的做法,但象pPloygon这样的类事实上并不提供普通Java类的功能。也就是说,它并不代表着一类对象,它只是Java语言组织代码的一种机制。
在上面这个例子中,改动代码的最终效果是使得应用Polygon功能的客户代码不必再从Polygon继承。Polygon类的功能现在已经由pPolygon类以过程为单位提供。客户代码只使用自己需要的代码,无需关心 Polygon类中自己不需要的功能。但它并不意味着在这种新式过程化编程中类的作用有所削弱。恰恰相反,在组织和封装对象数据成员的过程中,类起到了不可或缺的作用,而且正如本文接下来所介绍的,类通过多重接口实现多态性的能力本身也带来了卓越的代码重用支持。然而,由于用实例方法封装代码功能并不是首选的代码重用手段,所以通过类继承达到代码重用和多态性支持也不是最理想的。
措施二:把参数类型改成接口
正如Allen Holub在《Build User Interfaces for Object-Oriented Systems》中所指出的,在面向对象编程中,代码重用真正的要点在于通过接口参数类型利用多态性,而不是通过类继承:
“……我们通过对接口而不是对类编程达到代码重用的目的。如果某个方法的所有参数都是对一些已知接口的引用,那么这个方法就能够操作这样一些对象:当我们编写方法的代码时,这些对象的类甚至还不存在。从技术上说,可重用的是方法,而不是传递给方法的对象。”
在“措施一”得到的结果上应用Holub的看法,当某块代码能够编写为独立的全局过程时,只要把它所有类形式的参数改为接口形式,我们就可以进一步提高它的可重用能力。经过这个改动之后,过程的参数可以是实现了该接口的所有类的对象,而不仅仅是原来的类所创建的对象。由此,过程将能够对可能存在的大量的对象类型进行操作。
例如,假设有这样一个全局静态方法:
static public boolean contains(Rectangle rect, int x, int y) {...} |
这个方法用于检查指定的点是否包含在矩形里面。在这个例子中,rect参数的类型可以从Rectangle类改变为接口类型,如下所示:
static public boolean contains(Rectangular rect, int x, int y) {...} |
而Rectangular接口的定义是:
public interface Rectangular {Rectangle getBounds();} |
现在,所有可以描述为矩形的类(即,实现了Rectangular接口的类)所创建的对象都可以作为提供给pRectangular.contains()的rect参数。通过放宽参数类型的限制,我们使方法具有更好的可重用性。
不过,对于上面这个例子,Rectangular接口的getBounds方法返回 Rectangle,你可能会怀疑这么做是否真正值得。换言之,如果我们知道传入过程的对象会在被调用时返回一个Rectangle,为什么不直接传入 Rectangle取代接口类型呢?之所以不这么做,最重要的原因与集合有关。让我们假设有这样一个方法:
static public boolean areAnyOverlapping(Collection rects) {...} |
该方法用于检查给定集合中的任意矩形对象是否重叠。在这个方法的内部,当我们用循环依次访问集合中的各个对象时,如果我们不能把对象cast成为Rectangular之类的接口类型,又如何能够访问对象的矩形区域呢?唯一的选择是把对象 cast成为它特有的类形式(我们知道它有一个方法可以返回矩形),它意味着方法必须事先知道它所操作的对象类型,从而使得方法的重用只限于那几种对象类型。而这正是前面这个措施力图先行避免的问题!
措施三:选择最简单的参数接口类型
在实施第二个措施时,应该选用哪一种接口类型来取代给定的类形式?答案是哪一个接口完全满足过程对参数的需求,同时又具有最少的多余代码和数据。描述参数对象要求的接口越简单,其他类实现该接口的机会就越大——由此,其对象能够作为参数使用的类也越多。从下面这个例子可以很容易地看出这一点:
static public boolean areOverlapping(Window window1, Window window2) {...} |
这个方法用于检查两个窗口(假定是矩形窗口)是否重叠。如果这个方法只要求从参数获得两个窗口的矩形坐标,此时相应地简化这两个参数是一种更好的选择:
static public boolean areOverlapping(Rectangular rect1, Rectangular rect2) {...} |
上面的代码假定Window类型实现了Rectangular接口。经过改动之后,对于任何矩形对象我们都可以重用该方法的功能。
有些时候可能会出现描述参数需求的接口拥有太多方法的情况。此时,我们应该在全局名称空间中定义一个新的公共接口供其他面临同一问题的代码重用。
当我们需要象使用C语言中的函数指针一样使用参数时,创建唯一的接口描述参数需求是最好的选择。例如,假设有下面这个过程:
static public void sort(List list, SortComparison comp) {...} |
该方法运用参数中提供的比较对象comp,通过比较给定列表list中的对象排序list列表。sort对comp对象的唯一要求是要调用一个方法进行比较。因此,SortComparison应该是只带有一个方法的接口:
public interface SortComparison { boolean comesBefore(Object a, Object b); } |
SortComparison接口的唯一目的在于为sort提供一个它所需功能的钩子,因此SortComparison接口不能在其他地方重用。
总而言之,本文三个措施适合于改造现有的、按照面向对象惯例编写的代码。这三个措施与面向对象编程技术结合就得到了一种可在以后编写代码时使用的新式代码编写技术,它能够简化方法的复杂性和依赖关系,同时提高方法的可重用能力和内部凝聚力。
当然,这里的三个措施不能用于那些天生就不适合重用的代码。不适合重用的代码通常出现在应用的表现层。例如,创建程序用户界面的代码,以及联结到输入事件的控制代码,都属于那种在程序和程序之间千差万别的代码,这种代码几乎不可能重用
发表评论
-
BCD Conversion in java
2016-03-31 23:39 1838/** * Copyright 2010 Firat ... -
在java代码中获取JVM参数
2014-04-08 11:16 14254近日关注性能调优,关注JMX,发现java.lang.man ... -
GC日志分析配置与工具
2013-05-08 11:32 1353-verbose:gc(打印GC日志) -Xloggc:( ... -
java 实现HTTP PROXY
2012-12-06 17:21 7576日常应用中使用过很多次代理,主要停留在配置级别。 近期无意看 ... -
运行时获取方法调用堆栈信息(java)
2012-09-14 10:53 9699前几日系统流程回调时,一个方法莫名其妙被调用,无法定位调用点。 ... -
EL表达式在tomcat7.0下的new关键字不能使用
2012-08-24 17:25 4062最近生产系统部署个小应用,服务器选型tomcat7.0,一直运 ... -
xfire设置连接超时问题
2012-08-01 17:25 5145近期使用xfire作为客户端访问WS,结果因为目标主机假死 ... -
将多个对象写到一个文件
2012-07-20 17:08 1243来看一段ObjectOutputStream构造方法的源代码 ... -
多线程学习笔记:synchronized
2011-12-15 17:32 843Java语言的关键字,当它 ... -
(转)使用 Eclipse Memory Analyzer 检测内存泄漏问题
2011-12-14 18:10 1141本文是关于在开发 Talend RCP 过程中碰 ... -
多线程学习笔记:thread 线程中的sleep()、wait()、yield()、join()
2011-12-14 17:46 12781.sleep()方法 在指定时间内让当前正在执行的线程暂 ... -
jconsole监控JVM
2011-12-12 17:46 1561本地监控: Jconsole [processed] ... -
Java 6 JVM参数选项大全(中文版)
2011-11-03 15:19 1036本文 是基于最新的SUN官方 文档Java SE 6 ... -
Java实现远程屏幕监视
2011-10-19 17:40 732Robot robot = new Robot(); / ... -
java线程池 常用方法
2011-09-24 22:52 1385在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于 ... -
JAVA 调用Web Service的方法
2011-08-15 10:28 11541.使用HttpClient 用到的jar文件:comm ... -
JVM监控工具--jvmstat
2011-08-02 15:42 1275首先就是下载这个工具链接:http://java.sun.co ... -
java性能优化
2011-07-18 15:19 1103一、避免在循环条件中 ... -
jvm内存参数设定
2011-07-17 20:30 1378在开发java应用时经常出 ... -
怎样解决Java内存泄漏
2011-07-15 11:38 1455解决Java 内存泄漏 Java内存泄漏是每个 ...
相关推荐
关于提高Java代码可重用性的三个措施,本文将深入探讨并详细解释这些策略,帮助开发者在实际项目中更好地实现代码的复用。 ### 第一措施:优化类的设计 #### 设计模式的应用 设计模式是软件工程领域的重要概念,...
本文将介绍三种提高 Java 代码重用性的方法:改写类的实例方法、选择最简单的参数接口类型和把参数类型改成接口。 一、改写类的实例方法 在 Java 中,方法不能脱离类而单独存在。为了提高代码的重用性,我们可以把...
本资源包"JAVA代码、方法、运算符大全"是针对Java初学者和进阶者的一份宝贵资料,它涵盖了Java编程中的核心元素:代码、方法和运算符。 一、Java代码 Java代码是实现特定功能的指令集合,它由类(Class)、方法...
7. **泛型**:泛型引入于Java 5,提高了代码的类型安全性和重用性,允许在类、接口和方法中使用类型参数。 8. **枚举**:Java的枚举类型提供了一种创建固定数量常量的优雅方式,比传统的final static变量更安全。 ...
3. 提高代码重用性:自定义方法可以在程序中多次调用,提高代码的重用性和灵活性。 四、自定义方法的应用场景 自定义方法的应用场景非常广泛,例如: 1. 打印矩形:可以将打印矩形的代码提取出来,定义为一个方法...
过长的方法可以拆分为多个较小的方法,提高代码的可读性和可重用性。 2. **考虑客户端使用**:在设计类时,站在客户端的角度思考如何使用该类,确保类的接口清晰明了。 #### 五、类设计建议 1. **简化类的功能**:...
三、Java代码包的作用 1. 命名空间:避免类名冲突,同一包内的类可以有相同的名字。 2. 模块化:通过包,可以将相关的类组织在一起,形成功能模块。 3. 访问控制:通过包的访问修饰符,可以控制类和接口的可见性...
初学者需要学会封装、继承和多态这三个面向对象的基本特性。 3. **彩票程序代码**:彩票程序通常涉及到随机数生成、数组操作、条件判断等元素。在Java中,可以使用`java.util.Random`类来生成随机数,通过数组存储...
3. **方法(Methods)**:方法是实现代码重用的基本单元,通过定义和调用方法,可以实现特定功能,提高代码的可读性和可维护性。 4. **类与对象**:面向对象编程是Java的核心,类是对象的模板,对象则是类的实例。...
在Java编程语言中,类的重用是提高代码效率、减少冗余和增强软件可维护性的重要机制。本教程将深入探讨Java中的类重用,包括继承、接口、抽象类和多态等核心概念。 首先,我们要理解类的定义:在Java中,类是一种...
6. **继承**:Java支持单继承,一个类可以继承另一个类的属性和方法,从而实现代码重用。继承关键字是`extends`。 7. **多态**:多态性允许不同类型的对象对同一消息作出不同的响应。Java通过接口和方法的覆盖来...
以上就是关于Java代码重构、优化以及设计优化的一些关键点,这些知识不仅能提升代码质量,还能帮助开发者更好地应对项目中的各种挑战。通过深入学习《重构-改善既有代码的设计》这样的经典书籍,你可以进一步提升...
封装使得数据安全,继承允许代码重用,多态则增强了程序的灵活性。 3. **异常处理**:Java提供了异常处理机制,通过try-catch-finally语句块来捕获和处理运行时错误。这对于编写健壮的程序非常重要。 4. **集合...
4. **继承与多态**:继承允许子类从父类继承属性和方法,从而实现代码重用。多态则允许父类引用指向子类对象,提供了灵活性和可扩展性。 5. **异常处理**:Java的异常处理机制是程序健壮性的重要组成部分,通过try-...
在源代码中,你会找到使用`extends`关键字创建子类的例子,这有助于代码重用和多态性的实现。 4. **多态**:多态是对象可以表现出多种形式的能力。在Java中,多态通过接口和继承实现。源代码可能包含覆盖(override...
9. **泛型**:泛型提高了代码的类型安全性和重用性,是Java 5引入的重要特性。 10. **注解**:注解用于提供元数据,可以被编译器或JVM在编译时或运行时处理,简化编程任务。 11. **Swing与JavaFX**:这两个是Java...
19. **泛型**:泛型引入了类型参数,允许在类、接口和方法中使用类型参数,提高了代码的类型安全性和重用性。 20. **模块系统**:Java 9引入了模块系统,通过模块化设计,改善了大型项目中代码的组织和依赖管理。 ...
继承允许子类从父类继承属性和方法,实现代码重用;多态则允许不同对象对同一消息做出不同响应,增强了程序的灵活性。 4. **异常处理**:Java通过try-catch-finally结构来处理运行时可能出现的错误。异常是一种特殊...
9. 泛型:泛型引入了类型参数,允许在类、接口和方法中使用类型变量,提高了代码的类型安全性和重用性。 10. 集合框架:Java集合框架包括List、Set、Queue等接口,以及ArrayList、LinkedList、HashSet、HashMap等...
1. **定义本地方法**:首先,在Java代码中定义一个本地方法(native method),该方法声明为native,表示它是由本地代码实现的。 ```java public native int add(int x, int y); ``` 2. **生成头文件**:使用`...