从这篇文章 开始进入实战阶段的设计阶段,本文介绍内置类设计的最佳实践。
回顾一下,类(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