- 浏览: 132187 次
- 性别:
- 来自: 长沙->杭州
文章分类
- 全部博客 (39)
- 《Java面向对象设计最佳实践 》 (6)
- Software Architecture (0)
- Hardware Architecture (0)
- Software Engine (2)
- Article (1)
- Presentation (1)
- Miscellaneous (10)
- HotSpot JVM (1)
- 《深入Java并发》 (2)
- Java Core (2)
- Psychology (0)
- Java EE (6)
- Database (0)
- Performance Tuning (0)
- Troubleshotting (0)
- Web (0)
- Source Code (0)
- Open Source (0)
- Linux (0)
- NoSQL (2)
- Programming Languages (1)
- C/C++ (0)
- ASM (0)
- Advertisement (3)
- Principles of Management (0)
- asdasd (0)
- Test (0)
最新评论
-
hanmiao:
谢谢分享,上周遇到了壹个和 java.protocol.han ...
Java URL协议扩展实现 -
javatozhang:
没有细细的研究过URL类,文章不错!
Java URL协议扩展实现 -
bin_1715575332:
呵呵,很好的文章,这方面的文章不多啊。
Java URL协议扩展实现 -
hongli911:
extends被译成扩展????不是继承么?我呵呵
JSP自定义标签学习(基础) -
littlecar:
这个。。啥时候出来哈
《深入Java并发》- 目录(v0.1)
从这篇文章开始进入实战阶段的设计阶段,本文介绍内置类设计的最佳实践。
回顾一下,类(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书中提到超过四个参数的话,不利于维护),那么局部内置类是不是方便维护呢?
顺便提到,匿名内置类是局部内置类的一种。
不难发现,局部内置类的缺点是代码混杂(方法和类混在一起),如果依赖局部变量不多的情况下,在一定程度上面,增加了维护成本。
(其他内容,见附件)
- Java面向对象设计最佳实践_-_内置类设计.zip (8.9 KB)
- 下载次数: 143
- InnerNestedLocalClassDesign.zip (8.5 KB)
- 下载次数: 91
评论
比如:
Java 代码
1. final Boolean isReady = false;
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady = true;
8. }
9. });
final Boolean isReady = false;
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady = true;
}
});
我目前是这样解决的:
Java 代码
1. final Boolean[] isReady = {false};
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady[0] = true;
8. }
9. });
final Boolean[] isReady = {false};
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady[0] = true;
}
});
但是代码会很奇怪,能不能有其他的解决方式呢?比如Boolean自己改变自己的值?
还可以使用AtomicBoolean.
这种方式可行,谢谢了,呵,试了一下
public final void set(boolean newValue) {
value = newValue ? 1 : 0;
}
比如:
Java 代码
1. final Boolean isReady = false;
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady = true;
8. }
9. });
final Boolean isReady = false;
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady = true;
}
});
我目前是这样解决的:
Java 代码
1. final Boolean[] isReady = {false};
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady[0] = true;
8. }
9. });
final Boolean[] isReady = {false};
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady[0] = true;
}
});
但是代码会很奇怪,能不能有其他的解决方式呢?比如Boolean自己改变自己的值?
还可以使用AtomicBoolean.
比如:
Java 代码
1. final Boolean isReady = false;
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady = true;
8. }
9. });
final Boolean isReady = false;
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady = true;
}
});
我目前是这样解决的:
Java 代码
1. final Boolean[] isReady = {false};
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady[0] = true;
8. }
9. });
final Boolean[] isReady = {false};
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady[0] = true;
}
});
但是代码会很奇怪,能不能有其他的解决方式呢?比如Boolean自己改变自己的值?
你可以利用ThreadLocal来做。
比如:
Java 代码
1. final Boolean isReady = false;
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady = true;
8. }
9. });
final Boolean isReady = false;
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady = true;
}
});
我目前是这样解决的:
Java 代码
1. final Boolean[] isReady = {false};
2. notifyTaskExecutor.execute(new Runnable(){
3.
4. @Override
5. public void run() {
6. notifys.addAll(notifyBo.getNotifys(maxNum));
7. isReady[0] = true;
8. }
9. });
final Boolean[] isReady = {false};
notifyTaskExecutor.execute(new Runnable(){
@Override
public void run() {
notifys.addAll(notifyBo.getNotifys(maxNum));
isReady[0] = true;
}
});
但是代码会很奇怪,能不能有其他的解决方式呢?比如Boolean自己改变自己的值?
内部类还是非常强大的,尤其在android的界面构建时,更好做到界面与展现分离~
呵呵,是啊,感谢你回帖啊!
内部类还是非常强大的,尤其在android的界面构建时,更好做到界面与展现分离~
呵呵,好的,很多人认为这个东西简单,不过呢,很少看过之后,进行思考。
* 使用private final 是一种好习惯。:D
*/
private final class InnerClass {
public void setData(T newData) {
OuterClass3. this . data = newData;
// DOES Other things
}
}
发表评论
-
Java面向对象设计最佳实践 -方法范围设计
2010-06-20 14:48 0这篇文章介绍方法范围设计,这种设计是API开发人员容易忽视的部 ... -
Java面向对象设计最佳实践 - 方法设计(二)
2010-06-20 14:46 1259这篇文章介绍方法范围设计,这种设计是API开发人员容易 ... -
Java面向对象设计最佳实践 - 方法设计(一)
2010-05-17 10:53 2373在《类的设计基础知识 ... -
Java面向对象设计最佳实践 - 方法名称和注释设计
2010-05-17 04:37 0在《类的设计基础知识》文章中提到, 方法作为 命名的控制类 ... -
Java面向对象设计最佳实践 - 枚举设计
2010-05-12 11:23 2680对枚举类型印象大多来自于C 语言,在 C 语言中,枚举类 ... -
Java面向对象设计最佳实践 - 类的设计基础知识
2010-05-05 11:18 1325在开始类的设计之旅之前,首先引入一些基础知识,方便后续更详 ... -
Java面向对象设计最佳实践 - 概述
2010-04-16 11:43 1355根据笔者的经验,计划编写 “Java 面向对 ...
相关推荐
Java面向对象设计最佳实践_-_内置类设,是开发者的必备文档
Java面向对象设计最佳实践 - 方法设计(一)
习题解答-Java面向对象程序设计-邢国波-清华大学出版社.pdf习题解答-Java面向对象程序设计-邢国波-清华大学出版社.pdf习题解答-Java面向对象程序设计-邢国波-清华大学出版社.pdf习题解答-Java面向对象程序设计-邢...
Java面向对象程序设计---课件PPT,希望给能够学习者提供帮助,实现对计算机Java基础知识的掌握与理解,为后续学习做好铺垫,实现Java知识的灵活运用
13.1 TCP/IP协议简介 13.2 网络开发中的常用工具类 13.3 面向连接的TCP通信 13.4 无连接的UDP通信 13.5 UDP广播通信 13.6 局域网通信工具 第13章 Java网络编程 第13章-Java网络编程-Java面向对象程序设计教程-微课...
JAVA 面向对象程序设计教程 第9章Java Swing图形用户界面 第9章Java-Swing图形用户界面-Java面向对象程序设计教程-微课视频-程杰-清华大学出版社全文共27页,当前为第1页。 第9章Java Swing图形用户界面 第9章Java-...
Java面向对象程序设计--基本类型、数组和枚举类型Java面向对象程序设计--继承与接口.pptx
02Java面向对象设计(类-对象-构造方法-重栽).ppt该文档详细且完整,值得借鉴下载使用,欢迎下载使用,有问题可以第一时间联系作者~
Java面向对象程序设计--试题
Java面向对象程序设计--试题.doc
Java面向对象编程经典实例-模拟彩票 Eclipse工程
Java面向对象(进阶)-- Object类的详细概述
Java面向对象(高级)-- 包装类(wrapper)的使用
Java程序设计课程实验7-类和对象Java程序设计课程实验7-类和对象Java程序设计课程实验7-类和对象Java程序设计课程实验7-类和对象Java程序设计课程实验7-类和对象Java程序设计课程实验7-类和对象Java程序设计课程实验...
第三章-Java面向对象程序设计--JAVA教学课件.ppt该文档详细且完整,值得借鉴下载使用,欢迎下载使用,有问题可以第一时间联系作者~
Java面向对象(高级)-- 抽象类与抽象方法(或abstract关键字)
Java-面向对象设计-类和对象.docx
Java面向对象程序设计 21476-00.zip
目录 CONTENTS 01 5-1 简易公司人事管理 02 5-2 家电产品类设计 面向对象程序设计与实践-Java抽象类和接口[33页]全文共33页,当前为第3页。 01 简易公司人事管理 案例描述 案例分析 关联知识 案例实现 案例小结 ...
第1章_Java入门,第2章_基本数据类型,第3章_运算符、表达式和语句第4章_类与对象第5章_继承与接口第6章_内部类与异常类