喜欢这样的网吗?虽然,东西比较多,但是,还是蛮清晰的。无论你喜欢与否,这确实是个好东西,出自于SUN公司的牛人之作。它是JDK里的集合部分。当然,这样的东西,只能算是utilClass,如果你不想用,完全可以自己造几个轮子,反正,我是不会去造的,除非满足不了需求。
这个类层次基本是基于接口的。从顶层到下层,上层都是以抽象呈现的。然后,下层是具体的实现类。这没啥好说的,但是,关键是,如果让你设计这个的一个集合类层次。你会怎么设计呢?当然,跑得起来的代码也叫设计,这里就存在好的设计与糟糕的设计之分了。所以,设计时要考虑很多因素,比如可扩展性啦,可维护性啦,面向抽象编程啦,SRP,OCP等几个面向对象设计原则啦,反正就是很多,大大小小的综合因素权衡出一个设计结果。还有,千万不要小看对于这样的类层次的深刻理解,它对于你的面向对象思想有着极大的帮助。某某天,你参与了一个项目,首先得会做设计哦,并且,得设计好,不然,架构师就空有其名了。 当我在思考这个主题时,我产生了不少想法。有些可能是不成熟的。还是列出来下。
1. 自上而下设计
2. 自下而上设计
3. 基于接口的多个行为有异的类继承设计
1 . 自上而下设计
概念很明确,就是从接口抽象类开始。但是,你必须对于几个具体实现的抽象部分有着清晰的认识。并且你大致了解了这些具体实现类的规模以及职责所在,否则就变成了异形。然而,设计本身是个跌代的过程,所以,这是个不错的选择方案。
2。自下而上设计
你不了解具体实现类的规模以及职责所在,你只是随意或者仅仅针对于某一需求,写了一个辅助类。当然,你知道这个类是个有状态类,同时,它似乎在某个时刻跟别人有着某某关系(不知道是继承还是委托),所以,你没把这个类设计成为abstract, final, private constrcutor,OK,你只是保留着这种变化。然后,你又写了一个类,然后,发现这两个类有着共同的部分。然后,又写了一个,发现了不少新的东西。恩,很好,需要动作了,你开始思考怎么用设计模式把这些共同部分(可能在不同类有不同的实现)组织起来。对于,抽象方法,template模式能帮你解决大部分问题。同时,你需要到委托,所以,你还得考虑怎么使用委托才能得到良好的设计----可参考设计模式之进化论。
3。基于接口的多个行为有异的类继承设计
无论采用哪一种方式做设计。都能得到最终的好结果。而结果也基本是一致的。
下面是个例子。
你写了一个接口,并且提供了两实现类。
interface MyInterface{
public void println();
public void print();
public int size();
public boolean isEmpty();
}
class MyConcreteClassA implements MyInterface{
public boolean isEmpty() {
return size() == 0;
}
public void print() {
System.out.print("A");
}
public void println() {
System.out.println("A");
}
public int size() {
return 0;
}
}
class MyConcreteClassB implements MyInterface{
public boolean isEmpty() {
return size() == 0;
}
public void print() {
System.out.print("B");
}
public void println() {
System.out.println("B");
}
public int size() {
return 0;
}
}
然而,你又发现这两个实现类中有着共同的东西--isEmpty方法。所以,你得提取出来,顶层是个接口,没法放实现体。放哪里呢?有一个好的办法,就是把接口改成抽象类。记住,接口的条件比抽象类更强。改造如下:
abstract class MyAbstractClass{
public abstract void println();
public abstract void print();
public abstract int size();
public boolean isEmpty(){
return size() == 0;
}
}
class MyConcreteClassA extends MyAbstractClass{
public void print() {
System.out.print("A");
}
public void println() {
System.out.println("A");
}
public int size() {
return 0;
}
}
class MyConcreteClassB extends MyAbstractClass{
public void print() {
System.out.print("B");
}
public void println() {
System.out.println("B");
}
public int size() {
return 0;
}
}
这个template模式帮你解决了问题。同时,你也能保持住基于抽象编程这个好东西。
那么,还有一种方案,也就是JDK设计所使用的。
interface MyInterface{
public void println();
public void print();
public int size();
public boolean isEmpty();
}
abstract class MyAbstractClass implements MyInterface{
public abstract void println(); --------(1)
public abstract void print(); --------(2)
public abstract int size();
public boolean isEmpty(){
return size() == 0;
}
}
class MyConcreteClassA extends MyAbstractClass implements MyInterface{ --------(3)
public void print() {
System.out.print("A");
}
public void println() {
System.out.println("A");
}
public int size() {
return 0;
}
}
class MyConcreteClassB extends MyAbstractClass implements MyInterface{ --------(4)
public void print() {
System.out.print("B");
}
public void println() {
System.out.println("B");
}
public int size() {
return 0;
}
}
说明:抽象类MyAbstractClass 的抽象方法(1)和(2)可以不必显式写出来。因为抽象类会继承接口的抽象方法。同时,类MyConcreteClassA 定义中(3)的implements MyInterface{ 也可以不显式写出。尽管多了一个中间抽象类MyAbstractClass 层(有些公共方法或者缺省方法已在此实现),但是还是必须实现MyInterface中剩下的所有接口方法。
这样的结果,很好。所有具体类的公共方法被抽象基类实现了,同时,具体类也可以覆盖基类的缺省方法。对于子类是否支持某一个接口方法的解决,在抽象基类中实现一个缺省的方法更是有效。否则,就算是某一子类不支持该方法,也必须被实现。比如,你throw了一个 UnsupportedOperationException异常。这样很不好。
|
posted on 2008-08-14 15:34
zhqh 阅读(329)
评论(0) 编辑 收藏 所属分类:
jdk代码分析