造而来,每个层次所构造出来的实体,则可以作为上一层语言的基本原子使用。这样,我们就在通用的 Java 语言之上,逐步构建出了一种专用于表达界面布局的语言。比起传统的对象设计,这种方法具有更高的抽象层次和通用性。
我们来看一下界面布局语言中基本原子的实现细节,先来看一下 Component 的定义:
public interface Component {
public Component at(int x, int y, int width, int height);
public Component in(Container);
……
}
Button 的实现如下:
public class Button implements Component{
public JButton btn = new JButton();
public Component title(String t){
btn.setText(t);
return this;
}
public Component at(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(x,y,width,height);
btn.setBounds(rect);
return this;
}
public Component in(Container parent){
parent.add(btn);
return this;
}
……
}
从上面的代码中,读者会发现这种写法和传统的 API 写法风格的不同。在这种风格中,为了能够将调用形成一个句子,每个调用在结束时都返回了 this。另外,在给方法起名时也有不同的考虑,不只是关注于该方法的职责和功能,而是更关注于该方法名在整个句子这个上下文中是否通顺、是否更富表达力。
随着更多基本原子组件的编写,会发现 in 和 at 方法在很多组件中都重复出现,此时可以把它们提取到一个抽象基类中。这里这样写是为了清楚起见。
下面我们来看看 Empty 组件,beside 和 above 组合子的实现方法,它们都很简单。
public class Empty implements Component {
public Component at(int x,int y,int width,int height) {
return this;
}
public Component in(Container {
return this;
}
}
基于Java的界面布局DSL设计与实现(7)
时间:2011-03-07 IBM 孙鸣 邓辉
Empty 只是起到了一个布局空间占位的作用。beside 和 above 的实现如下:
public class beside implements Component {
private Component left,right;
private float ratio;
public beside(Component left,Component right,float ratio){
this.left = left;
this.right = right;
this.ratio = ratio;
}
public Component at(int x,int y,int width,int height) {
left.at(x, y, width*ratio,height);
right.at(x+ width*ratio, y, width*(1-ratio),height);
return this;
}
public Component in(Container parent) {
left.in(parent);
right.in (parent);
return this;
}
……
}
public class above implements Component {
private Component up,low;
private float ratio;
public above(Component up, Component low, float ratio){
this.up = up;
this.low = low;
this.ratio = ratio;
}
public Component at(int x,int y,int width,int height) {
up.at(x, y, width,height*ratio);
low.at(x, y+height*ratio, width,height*(1-ratio));
return this;
}
public Component in(Container parent) {
up.in(parent);
low.in (parent);
return this;
}
……
}
为了保证组合操作的闭包性质,这两个组合子都实现了 Co |