设计模式(一):接口型模式介绍
1 接口
类的接口 (interface) 就是该类允许其他类对象访问的方法和字段的集合。接口作为对象必须实现的承诺。接口永远不可能被实例化为对象,因此只能定义虚方法和常量字段。
作用:
限制了对象之间的交互(交互可以只用interface来完成,interface进行限制)
与抽象类的区别:
一个类可以实现(implements)任意多个接口,但只能继承(extend)一个抽象类。
一个抽象类可有非抽象方法,可以定义构造器,接口的所有方法都是抽象的。
接口只能声明static final 常量,因为一般成员变量无法实例化。
总之,接口只是一种限制形式。
2 Adapter模式
目的:利用现有的类,满足需要的接口
2.1 接口适配
情形:应用程序需要调用RequiredInterface接口,包含requiredMethod方法,而一个现存的类ExistingClass是一个已有的实现,但接口与应用程序的接口不一致,因此采用接口适配模式。
方法:
定义一个新类NewClass,继承ExistingClass,并实现RequiredInterface接口。
2.2 对象适配器
情形:应用程序需要调用RequiredClass类,包含requiredMethod()方法,而一个现存的类ExistingClass是一个相同功能的实现
问题:java中只允许单继承,不能同时继承RequiredClass和ExisitingClass两个类。
解决:定义NewClass,继承RequiredClass(满足应用程序调用要求),并包含ExistingClass的实例对象作为成员变量,NewClass在实现requiredMethod()方法时调用ExistingClass实例对象的usefulMethod()方法就可以了。
2.3 实例:JTable的使用
本例是一个基于对象适配器的模式实例
Javax.swing.JTable类定义了一个常规的二维单元表。构造一个JTable的实例需要实例化成员变量TableModel(接口),为了方便,java类库部分实现了接口构造了抽象类AbstractTableModel,只需实现getColumnCount() getRowCount()和getValueAt()三个抽象方法而已,因此选择对象适配模式。
具体表格里填的是什么,当然是需要用户类自己定义,然后适配TableModel接口。
可以看到,适配类RocketTableModel内包含了Rocket实例对象的数组,抽象类的方法都可以通过调用Rocket对象来实现。
程序,来自www.oozinoz.com
主程序:
-
public class ShowRocketTable {
-
public static void main(String[] args) {
-
setFonts();
-
JTable table = new JTable(getRocketTable());
-
table.setRowHeight(36);
-
JScrollPane pane = new JScrollPane(table);
-
pane.setPreferredSize(new java.awt.Dimension(300, 100));
-
display(pane, " Rockets");
-
}
-
-
/**
-
* Display a Swing component. We'll refactor this later into a nice facade.
-
*
-
* @param c the component to display
-
* @param title the window title
-
*/
-
public static void display(Component c, String title) {
-
JFrame frame = new JFrame(title);
-
frame.getContentPane().add(c);
-
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
frame.pack();
-
frame.setVisible(true);
-
}
-
-
private static RocketTableModel getRocketTable() {
-
Rocket r1 = new Rocket("Shooter", 1.0, new Dollars(3.95), 50.0, 4.5);
-
Rocket r2 = new Rocket("Orbit", 2.0, new Dollars(29.03), 5000, 3.2);
-
return new RocketTableModel(new Rocket[] { r1, r2 });
-
}
-
-
private static void setFonts() {
-
Font font = new Font("Dialog", Font.PLAIN, 18);
-
UIManager.put("Table.font", font);
-
UIManager.put("TableHeader.font", font);
-
}
-
}
适配类RocketTableModel:
-
public class RocketTableModel extends AbstractTableModel {
-
protected Rocket[] rockets;
-
protected String[] columnNames = new String[] { "Name", "Price", "Apogee" };
-
-
/**
-
* Construct a rocket table from an array of rockets.
-
* @param rockets an array of rockets
-
*/
-
public RocketTableModel(Rocket[] rockets) {
-
this.rockets = rockets;
-
}
-
-
/**
-
* @return the number of columns in this table.
-
*/
-
public int getColumnCount() {
-
return columnNames.length;
-
}
-
-
/**
-
* @param index which column is interesting
-
* @return the name of the indicated column
-
*/
-
public String getColumnName(int i) {
-
return columnNames[i];
-
}
-
-
/**
-
* @return the number of rows in this table.
-
*/
-
public int getRowCount() {
-
return rockets.length;
-
}
-
-
/**
-
* @param row which row is interesting
-
* @param col which column is interesting
-
* @return the value at the indicated row and column.
-
*/
-
public Object getValueAt(int row, int col) {
-
switch (col) {
-
case 0:
-
return rockets[row].getName();
-
case 1:
-
return rockets[row].getPrice();
-
case 2:
-
return new Double(rockets[row].getApogee());
-
default:
-
return null;
-
}
-
}
-
}
原类Rocket:
-
public class Rocket extends Firework {
-
private double apogee;
-
-
private double thrust;
-
-
/**
-
* Allow creation of empty objects to support reconstruction from persistent
-
* store.
-
*/
-
public Rocket() {
-
}
-
-
/**
-
* Create a rocket with all its expected properties. See the superclass for
-
* descriptions of other parameters
-
*
-
* @param apogee
-
* The height (in meters) that the rocket is expected to reach
-
* @param thrust
-
* The rated thrust (or force, in newtons) of this rocket
-
*/
-
public Rocket(String name, double mass, Dollars price, double apogee,
-
double thrust) {
-
super(name, mass, price);
-
setApogee(apogee);
-
setThrust(thrust);
-
}
-
-
/**
-
* The height (in meters) that the rocket is expected to reach.
-
*/
-
public double getApogee() {
-
return apogee;
-
}
-
-
public void setApogee(double value) {
-
apogee = value;
-
}
-
-
/**
-
* The rated thrust (or force, in newtons) of this rocket.
-
*/
-
public double getThrust() {
-
return thrust;
-
}
-
-
public void setThrust(double value) {
-
thrust = value;
-
}
-
}
当然,getName() getPrice()这两个方法在超类Firework中定义。