【读码练习/cron4j】(二)半个设计模式:不暴露底层表现(简化了的迭代器模式)

重读笔记第一次:

这篇总结写的不好,自己的东西重看的也比较累,不高兴改了,就写这里吧。

主要总结迭代器的两个功能的左边那个:不暴露底层,也可以说是统一接口以备泛用。

其实cron4j也不是没有返回迭代器,只是不如教科书上的那样死板而已。

再补充下java类库的aggregate角色和iterator角色。

分别是java.lang.iterable和java.util.iterator

就这样吧

经典的迭代器模式,有两个功能

1、提供一个方式顺序访问集合

2、不暴露底层的表现形式。

经典的迭代模式有四个角色。

aggregate、concreteAggregate、iterator、concreteIterator。

aggreate里通常有一个方法 iterator  createrIterator(); 返回迭代器

iterator里也通常有一个方法 next() 从集合顺序访问元素

 


cron4j的简化

在cron4j这个模式得到简化。(TaskCollector是aggregate角色,FileTableCollector是concreteAggregate)

1、没有了抽象的iterator角色。

2、interator也没有了next()。

publicinterface TaskCollector {
public TaskTable getTasks();
}

 

 1 class FileTaskCollector implements TaskCollector {
2
3 private ArrayList files =new ArrayList();
4
5 publicsynchronizedvoid addFile(File file) {
6 files.add(file);
7 }
8
9 publicsynchronizedvoid removeFile(File file) {
10 files.remove(file);
11 }
12
13 publicsynchronized File[] getFiles() {
14 int size = files.size();
15 File[] ret =new File[size];
16 for (int i =0; i < size; i++) {
17 ret[i] = (File) files.get(i);
18 }
19 return ret;
20 }
21
22 publicsynchronized TaskTable getTasks() {
23 TaskTable ret =new TaskTable();
24 int size = files.size();
25 for (int i =0; i < size; i++) {
26 File f = (File) files.get(i);
27 TaskTable aux =null;
28 try {
29 aux = CronParser.parse(f);
30 } catch (IOException e) {
31 Exception e1 =new Exception("Cannot parse cron file: "
32 + f.getAbsolutePath(), e);
33 e1.printStackTrace();
34 }
35 if (aux !=null) {
36 int auxSize = aux.size();
37 for (int j =0; j < auxSize; j++) {
38 ret.add(aux.getSchedulingPattern(j), aux.getTask(j));
39 }
40 }
41 }
42 return ret;
43 }
44
45 }

 

 

 1 publicclass TaskTable {
2
3 privateint size =0;
4
5 private ArrayList patterns =new ArrayList();
6
7 private ArrayList tasks =new ArrayList();
8
9 publicvoid add(SchedulingPattern pattern, Task task) {
10 patterns.add(pattern);
11 tasks.add(task);
12 size++;
13 }
14
15 publicint size() {
16 return size;
17 }
18
19 public Task getTask(int index) throws IndexOutOfBoundsException {
20 return (Task) tasks.get(index);
21 }
22
23
24 public SchedulingPattern getSchedulingPattern(int index)
25 throws IndexOutOfBoundsException {
26 return (SchedulingPattern) patterns.get(index);
27 }
28
29 publicvoid remove(int index) throws IndexOutOfBoundsException {
30 tasks.remove(index);
31 patterns.remove(index);
32 size--;
33 }
34
35 }



这样的简化好还是不好呢?

从代码看,迭代器的迭代方法next()被省略掉了。如果要遍历的话,必须通过size()、getTask(index),getSchedulingPattern(index)

但如果我们去实现一个next方法,可能还要把一对Task、和Pattern包装成一个类,然后还要再包装他们的方法。

这样似乎就得不偿失了。

 

 

思考

迭代器的重点之一是把集合(File对象或者其他Object)和表现形式(TaskTable)分离。可以单独用于场景

迭代器模式,如果要迭代的对象复杂,不易封装,next()方法不要也罢。

模式对应场景可以提高对应的效率,不必拘泥形式。

posted @ 2011-08-28 15:01  倚楼无语F5  阅读(513)  评论(0编辑  收藏  举报