- 浏览: 35269 次
- 性别:
- 来自: 郑州
文章分类
最新评论
-
yekui:
把Liberarise 重新导,src等都从新倒 即可解决。
tomcat编译工程之后classes文件夹下没有文件或者缺失文件解决办法 -
w1113:
刚才也碰到你的这个问题,编译后的class文件发布不上去,最后 ...
tomcat编译工程之后classes文件夹下没有文件或者缺失文件解决办法 -
苏叶晚晚:
我也遇到了同样。。。无奈的问题。唉==
用楼主的奇思妙想的办法 ...
tomcat编译工程之后classes文件夹下没有文件或者缺失文件解决办法
Java面向对象设计最佳实践
内置类设计
从这篇文章开始进入实战阶段的设计阶段,本文介绍内置类设计的最佳实践。
回顾一下,类(Class)作为Java编程语言中的基本单元模块,提供了面向对象的四种基本性质:抽象性、封装性、继承性和多态性。
在面向对象设计原则中,尽可能偏好方法,而非字段(或属性)。简单的说,方法更好的表达语义。因此,在方法实现过程中,经常会遇到类似的情景,接口方法method1 调用其他方法来完成功能需要。无非有三种情况,利用本类的(静态或者实例的)方法,调用某个类的静态可访问的方法和某个实例可访问的实例方法。但是,良好类设计是尽量的隐藏实现细节,简单清晰地表达语义。
客户端程序只关心输入和输出,没有必要去关心中间的细节。回到上述的三情况,尽可能隐藏本类和他类的细节。如果本类和他类相互耦合,那么扩张性和易用性受到一定程度的影响。但是设计人员想让本类和他类相互知晓,或者范围限制(主要是指类之间的访问限制)尽可能小,那么内置类是一个很好的办法。
笔者把内置类分为三类:类内置类(Nested Class),实例内置类(Inner Class)和布局内置类(Local Class)。下面分别介绍这三种类的使用场景和设计方法。
类内置类(Nested Class),在内置类中使用得最多的一类。其作为类的一部分,随外层类(Enclosing Class)顺序地被加载。它的好处是,定义的类内置类仅此一次被创建并加载,可视外层类的类成员。那么使用场景不难得出,对于实例成员不感冒,只关心类成员,并且减少没有必要重复类的创建和加载。在大多数实际情况中,这个模式已经足够了。举一个的JDK里面的例子,迭代Map的时候,键值对实体接口java.util.Map.Entry<K, V>,其定义在java.util.Map<K, V>接口中,自然其修饰符是public static final。
为了客户端程序能够利用java.util.Map.Entry<K, V>,JDK暴露了它。一般来说,private final static是通用的设计。外层类对其是完全可视的,因此private 是没有问题的。至于final的修饰,要谈到笔者设计经验中的一个原则,尽量使用final修饰可修饰的。其中有几个好处,比如线程安全、拒绝子类、标准化(在后面的设计文章中会详细说明)等。在内置类设计中,不应该期望其他类继承这个类,更不要期望其他人会使用的内置类了。又回到JDK,大家会发现java.util.HashMap<K,V>内部定义不少的类内置类。
使用下了代码实例补充说明上述:
package org.mercy.design;
/**
* OuterClass 是外层类,NestedClass 类内置类
* @author mercyblitz
*/
public class OuterClass {
/**
* private final static 是类内置类的通用设计技巧
*/
private final static class NestedClass {
}
}
代码-1
如果OuterClass类中有实例变量的话,显然NestedClass是不可见的,也是不适用的(因为它是类的一部分)。
这个时候,利用实例内置类可以解决这类问题。
示例代码如下:
package org.mercy.design;
/**
* OuterClass2 是外层类,InnerClass 实例内置类
*
* @author mercyblitz
*/
public class OuterClass2 {
private String message;
/**
* 使用private final 是一种好习惯。:D
*/
private final class InnerClass {
/**
* 输出OuterClass2消息
*/
private void outputMessageFromOuterClass2() {
// 注意,this的命名空间
System.out.println(OuterClass2.this.message);
}
}
}
代码-2
在“代码-2”中,InnerClass利用OuterClass2的message字段作为输出。
可能有人会说,InnerClass这种实例内,为了得到这个类,不得不创建一个实例,太浪费资源了,为什么不直接把OuterClass实例作为参数,直接传入到InnerClass的方法呢?
没错,可以那么做。不过单从访问外层类的实例变量而言,利用实例内置类是有点显得浪费。如果客户端利用了泛型编程的话,情况就会不同。
总所周知,泛型设计能够提高灵活性,可是也有很多限制。模版参数类型是跟随其寄主类的,模板参数类型是不会写入class文件中的,这就是为什么反射(Reflection)不能解析出类的模板参数类型。但是,模板参数类型在实例(对象)范围是可用的(或可视的)。如果内置类中想要利用外层类的模板参数类型的话,那么实例内置类就有很大用处。
例子如下:
package org.mercy.design;
/**
* OuterClass3 是外层类,InnerClass 实例内置类
*
* @author mercyblitz
* @param <T>
* 模板参数类型,实例内置类可以利用
*/
public class OuterClass3<T> {
private T data;
/**
* 使用private final 是一种好习惯。:D
*/
private final class InnerClass {
public void setData(T newData) {
OuterClass3.this.data = newData;
// DOES Other things
}
}
}
代码-3
“代码-3”中的实例内置类利用外层类OuterClass3中的模板参数T,作为setData参数的类型。
看似类内置类和实例内置类已经足够使用了。考虑这么一个场景,一个方法利用了内置类来实现功能,这个方法中的变量需要被内置类来利用,通常可以把变量作为参数,传入内置类构造器或者其方法中,这也是通常的方法。不过利用布局内置类(Local Class)更为方便,因为局部内置类是在块中(方法也是一种特殊的块)定义的,这样就很好的解决了上下文的参数传递问题。
参看代码:
package org.mercy.design;
/**
* OuterClass4 是外层类,Printer 局部内置类
*
* @author mercyblitz
*/
public class OuterClass4 {
public void print(byte[] bytes) {
final String message = new String(bytes);
/**
* 名为Printer LocalClass,不必把message作为参数传递。
*/
class Printer {
private void doPrint() {
System.out.println(message);
}
}
new Printer().doPrint();
}
public static void main(String[] args) {
new OuterClass4().print("AAAAAAA".getBytes());
}
}
代码-4
在“代码-4”的示例中,有人可能会说,这看不出什么好处呀?!如果内置类依赖的变量超过4个(Effective Java书中提到超过四个参数的话,不利于维护),那么局部内置类是不是方便维护呢?
顺便提到,匿名内置类是局部内置类的一种。
不难发现,局部内置类的缺点是代码混杂(方法和类混在一起),如果依赖局部变量不多的情况下,在一定程度上面,增加了维护成本。
最后的篇幅来总结一下这几种内置类的特点,以及使用场景和设计技巧。
共同特点,不想暴露并且不期望被外部使用或者扩张(强调一下,一般类中私有和包内私用都是好的设计技巧),通过类的四大特性提供更优于方法的方法和外部内实现交互,从而达到良好设计目的。
对于类内置类(Nested Class),适合的绝大多数内置类场景,利于维护。但不适合利用外层类模板参数类型和实例变量。
就实例内置类(Inner Class),适合利用外层类模板参数类型和实例变量,更好的弹性设计。可是加载其类时,必须实例化外部类,造成不必要开销,因此不是必须,尽量使用类内置类。
局部内置类(Local Class),适合多局部变量依赖的场景,提高可维护性,相反就不适合。
因此,内置类的设计和其他面向对象设计类似,根据适合的场景来合理设计。在设计上,没有最好,只有更好。笔者精力和经验优先,希望大家指正,谢谢。
发表评论
-
经典sql语句大全
2011-03-07 17:42 828一、基础 1、说明:创建数据库CREATE DATABA ... -
Spring AOP处理日志
2011-03-07 17:39 1201Spring AOP处理日志 AOP正 ... -
验证码相关2
2011-03-07 16:57 656登录的jsp页面: <%@ page language= ... -
验证码相关
2011-03-07 16:55 795public class RandomNumUtil { ... -
LoginInterceptor (用户登录拦截器类)
2011-03-07 16:54 1815public class LoginInterceptor e ... -
PageHelper (分页导航类,根据当前页计算导航链接)
2011-03-07 16:54 2569public class PageHelper { ... -
Pager(分页查询类)
2011-03-07 16:53 1262public class Pager extends Hibe ... -
FileTool (文件工具类)
2011-03-07 16:51 1566public class FileTool { ... -
CustomActionSupport (继承ActionSupport的类)
2011-03-07 16:50 781public class CustomActionSuppor ... -
StringTool(字符串工具类)
2011-03-07 16:49 1359public class StringTool { ... -
DateFormatTool(日期格式和字符串格之间转换类,日期转换器用到此类)
2011-03-07 16:49 1917public class DateFormatTool { ... -
LongConvert(Long类型转换器)
2011-03-07 16:48 915public class LongConvert extend ... -
IntConvert(整数类型转换器)
2011-03-07 16:47 792public class IntConvert extends ... -
DateConvert(日期类型转换器)
2011-03-07 16:47 1693public class DateConvert extend ... -
Xwork-conversion.properties资源文件全文
2011-03-07 16:46 1109java.sql.Timestamp=com.wyt.comm ... -
Struts.priperties配置文件全文
2011-03-07 16:46 757struts.objectFactory=spring str ... -
SSH2整合过程中出现的错误及解决方法
2011-03-07 16:45 1077老是报,ERROR [main] (Conte ... -
SSH2整合的顺序
2011-03-07 16:44 9741. 添加Spring 2.0的Libraries 选择 ... -
log4j.properties资源文件全文
2011-03-07 16:43 657log4j.rootLogger=INFO,ERROR,con ... -
init.properties资源文件全文
2011-03-07 16:42 1496datasource.type=mssql datasourc ...
相关推荐
Java面向对象设计最佳实践_-_内置类设,是开发者的必备文档
Java面向对象设计最佳实践 - 方法设计(一)
设计模式代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临 的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误...
设计模式经验丰富的面向对象软件开发人员使用的最佳实践。
设计模式代表了经验丰富的面向对象软件开发人员所使用的最佳实践。设计模式是针对软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是由众多软件开发人员在相当长的一段时间内通过反复试验而获得...
Chock充满了演示如何充分利用现代Java API和开发最佳实践的示例,这本经过全面修订的书籍包含有关Java Concurrency Utilities的新资料。 本书的第一部分提供了Java编程语言和Java平台的核心运行时方面的快节奏,...
Java是一种高性能、跨平台的面向对象编程语言。它由Sun Microsystems(现在是Oracle Corporation)的James Gosling等人在1995年推出,被设计为一种简单、健壮、可移植、多线程、动态的语言。Java的主要特点和优势...
一本使用Java语言讲述设计模式的电子书,设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。
本书面向的主要读者是具备一定 Java 基础的开发人员和在校学生。本书中不涉及 Java 的基本语法,因此不适合 Java 初学者阅读。如果只对 Java SE 7 中的新特性感兴趣,可以阅读第 1 章到第 6 章;如果对 Java 中的...
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...
pdf格式可用Foxit Reader打开 包括Java程序的异常处理、编码规则和组织结构、内存管理、面向对象的设计与实现、性能调整,Java编码最佳实践,Java类库的高级用法及与当代软件工程的结合等。
通过阅读和分析Java源码,可以帮助学习者深入理解Java编程语言的特性和最佳实践,提高编程技能,解决实际问题。同时,Java源码也是开发人员进行软件开发的基础,可以用于构建各种类型的应用程序和系统。 这个Java...
JAVA图书馆书库管理系统设计(源代码)为大学生提供了一个实际的毕业设计项目案例,不仅可以用于学习JAVA编程和软件开发的最佳实践,还能帮助他们理解和掌握现代图书馆管理系统的运作机制。通过这个项目,学生可以...
Java注解和最佳实践 JavaIO流 多线程 深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承、封装、多态的实现原理 容器 Java集合类总结 Java集合详解1:一文读懂ArrayList,Vector与Stack使用...
面向对象篇:深入讲解面向对象的概念、特性以及Java中的实现方式,包括类、对象、封装、继承、多态等。 高级特性篇:涵盖Java中的高级特性,如集合框架、泛型、异常处理、多线程、网络编程等,帮助读者提升Java编程...
它详细介绍了Java编程中的有效实践和最佳实践,如何避免常见的错误和陷阱。 《深入理解Java虚拟机》:这本书是Java虚拟机编程的经典教材,适合中级和高级开发者。它详细介绍了Java虚拟机的原理和内部实现,以及如何...
Java注解和最佳实践 JavaIO流 多线程 深入理解内部类 javac和javap Java8新特性终极指南 序列化和反序列化 继承封装多态的实现原理 集合类 Java集合类总结 Java集合详解:一文读懂ArrayList,Vector与Stack使用方法和...
廖雪峰 Java 教程 Java教程 Java快速入门 Java简介 安装JDK 第一个Java程序 ...Java代码助手 ...Java程序基础 ...最佳实践 单元测试 编写JUnit测试 使用Fixture 异常测试 条件测试 参数化测试
它被设计成一种可移植、面向对象和跨平台的语言,具有简单性、可靠性和安全性的特点。 以下内容是在大学时候接触的: 学习Java的基础知识:开始之前,你需要理解计算机编程的基本概念和术语。了解变量、条件语句、...