经过上面的分析建模,我们可以开始实现架构了,从上面的概念模型我们可以很容易地抽象出相应的接口来。首先,我们看看 EditorFacade 类,基于我们上面的讨论,不同的界面可能有不同的需求,比如有的要支持 transaction-事务,那么 EditorFacade 的实现就会不同,所以我们有必要提取出一个接口来表示,下面列出了这个接口 IEditorFacade:
清单1:IEditorFacade.java
2
3 public void show();
4
5 public IInputDataObject getInputData();
6
7 public void setInputData(IInputDataObject inputData);
8
9 public IOutputDataObject getOutputData();
10
11 public void setOutputData(IOutputDataObject outputData);
12
13 public boolean isFinishedOK();
14
15 public Composite getRootComposite();
16
17 public void setAssembler(IEditorAssembler assembler);
18
19 public void close(boolean status);
20
21 }
22
23
那么 EditorFacade 类的部分代码如下:
清单2:EditorFacade.java
2
3 private Shell shell;
4
5 // validate if editor is closed with OK or Cancel
6
7 private boolean finishedOK;
8
9 // input data
10
11 private IInputDataObject inputData;
12
13 // output data
14
15 private IOutputDataObject outputData;
16
17 private Composite composite;
18
19 private IEditorAssembler assembler;
20
21 private void createSShell() {
22
23 shell = new Shell();
24
25 shell.setLayout(new GridLayout());
26
27 createComponent();
28
29 }
30
31 private void createComponent() {
32
33 composite = new Composite(shell, SWT.NONE);
34
35 ………
36
37 assembler.create(this);
38
39 }
40
41 public void show() {
42
43 this.shell.open();
44
45 assembler.showPreInfo();
46
47 }
48
49 public EditorFacade(IEditorAssembler assembler, IInputDataObject inputData) {
50
51 this.assembler = assembler;
52
53 this.inputData = inputData;
54
55 this.createSShell();
56
57 }
58
59 public Composite getRootComposite() {
60
61 return composite;
62
63 }
64
65 public void close(boolean status) {
66
67 finishedOK = status;
68
69 this.shell.close();
70
71 }
72
73 }
74
75
下一步,我们将两个 IO 数据类定义出来,很显然,不同的界面会有不同的输入输出数据,在这里我们只能定义出两个抽象的接口 IInputDataObject 和 IOutputDataObject,它们继承了序列化 java.io.Serializable 接口,里面并无其它内容。这里注意一点,空的接口并非无意义,它可以起到标识的作用,另外,它隐藏了具体实现,在传递数据时传递者不用知道具体数据内容,这样传递者类具有更好的重用性,而且具体数据类也不用暴露给不该知道它的类-传递者类,这正是另一个面向对象的基本原则-迪米特法则(LoD):不要和陌生人说话。下面给出 IInputDataObject 的清单:
清单3:IInputDataObject.java
2
3 }
4
5
接下来,我们看看 EditorAssembler 类的实现,根据前面的讨论,它封装了界面的装配逻辑,一定会被修改的,那么我们就需要一个接口 IEditorAssembler 来规范它的行为,在这里我还给出了一个抽象类 AbstractEditorAssembler,实现了装载单个 EditorComposite 的方法,另外我还给出了一个具体的 EditorAssembler 类,这是一个每次只装载一个 EditorComposite 的例子,代码清单如下:
清单4:IEditorAssembler.java
2
3 /**
4
5 * create editor body and init
6
7 * @param editor
8
9 */
10
11 public void create(IEditorFacade editor);
12
13 /**
14
15 * create editor composite
16
17 * @param editor
18
19 * @param compositeClassID
20
21 * :composite class name,e.g. test.view.TestComposite
22
23 * @return
24
25 */
26
27 public IEditorComposite createComposite(IEditorFacade editor,
28
29 String compositeClassID);
30
31 /**
32
33 * show exist info in UI for update.
34
35 */
36
37 public void showPreInfo();
38
39 }
40
41 public interface IEditorAssembler {
42
43 /**
44
45 * create editor body and init
46
47 * @param editor
48
49 */
50
51 public void create(IEditorFacade editor);
52
53 /**
54
55 * create editor composite
56
57 * @param editor
58
59 * @param compositeClassID
60
61 * :composite class name,e.g. test.view.TestComposite
62
63 * @return
64
65 */
66
67 public IEditorComposite createComposite(IEditorFacade editor,
68
69 String compositeClassID);
70
71 /**
72
73 * show exist info in UI for update.
74
75 */
76
77 public void showPreInfo();
78
79 }
80
81
清单5:AbstractEditorAssembler.java
2
3 public IEditorComposite createComposite(IEditorFacade editor,
4
5 String compositeClassID) {
6
7 IEditorComposite body;
8
9 body = EditorCompositeFactory.createComposite(compositeClassID, editor);
10
11 body.create(editor.getRootComposite());
12
13 body.setEditor(editor);
14
15 return body;
16
17 }
18
19 ………………………………….
20
21 }
22