设计模式(一):接口型模式介绍

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

主程序:

  1. public class ShowRocketTable {
  2.     public static void main(String[] args) {
  3.         setFonts();
  4.         JTable table = new JTable(getRocketTable());
  5.         table.setRowHeight(36);
  6.         JScrollPane pane = new JScrollPane(table);
  7.         pane.setPreferredSize(new java.awt.Dimension(300, 100));
  8.         display(pane, " Rockets");
  9.     }
  10.  
  11.     /**
  12.      * Display a Swing component. We'll refactor this later into a nice facade.
  13.      *
  14.      * @param c the component to display
  15.      * @param title the window title
  16.      */
  17.     public static void display(Component c, String title) {
  18.         JFrame frame = new JFrame(title);
  19.         frame.getContentPane().add(c);
  20.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  21.         frame.pack();
  22.         frame.setVisible(true);
  23.     }
  24.  
  25.     private static RocketTableModel getRocketTable() {
  26.         Rocket r1 = new Rocket("Shooter", 1.0, new Dollars(3.95), 50.0, 4.5);
  27.         Rocket r2 = new Rocket("Orbit", 2.0, new Dollars(29.03), 5000, 3.2);
  28.         return new RocketTableModel(new Rocket[] { r1, r2 });
  29.     }
  30.  
  31.     private static void setFonts() {
  32.         Font font = new Font("Dialog", Font.PLAIN, 18);
  33.         UIManager.put("Table.font", font);
  34.         UIManager.put("TableHeader.font", font);
  35.     }
  36. }

适配类RocketTableModel:

  1. public class RocketTableModel extends AbstractTableModel {
  2.     protected Rocket[] rockets;
  3.     protected String[] columnNames = new String[] { "Name", "Price", "Apogee" };
  4.  
  5.     /**
  6.      * Construct a rocket table from an array of rockets.
  7.      * @param rockets an array of rockets
  8.      */
  9.     public RocketTableModel(Rocket[] rockets) {
  10.         this.rockets = rockets;
  11.     }
  12.  
  13.     /**
  14.       * @return the number of columns in this table.
  15.      */
  16.     public int getColumnCount() {
  17.         return columnNames.length;
  18.     }
  19.  
  20.     /**
  21.      * @param index which column is interesting
  22.      * @return the name of the indicated column
  23.      */
  24.     public String getColumnName(int i) {
  25.         return columnNames[i];
  26.     }
  27.  
  28.     /**
  29.      * @return the number of rows in this table.
  30.      */
  31.     public int getRowCount() {
  32.         return rockets.length;
  33.     }
  34.  
  35.     /**
  36.      * @param row which row is interesting
  37.      * @param col which column is interesting
  38.      * @return the value at the indicated row and column.
  39.      */
  40.     public Object getValueAt(int row, int col) {
  41.         switch (col) {
  42.         case 0:
  43.             return rockets[row].getName();
  44.         case 1:
  45.             return rockets[row].getPrice();
  46.         case 2:
  47.             return new Double(rockets[row].getApogee());
  48.         default:
  49.             return null;
  50.         }
  51.     }
  52. }

原类Rocket:

  1. public class Rocket extends Firework {
  2.     private double apogee;
  3.  
  4.     private double thrust;
  5.  
  6.     /**
  7.      * Allow creation of empty objects to support reconstruction from persistent
  8.      * store.
  9.      */
  10.     public Rocket() {
  11.     }
  12.  
  13.     /**
  14.      * Create a rocket with all its expected properties. See the superclass for
  15.      * descriptions of other parameters
  16.      *
  17.      * @param apogee
  18.      * The height (in meters) that the rocket is expected to reach
  19.      * @param thrust
  20.      * The rated thrust (or force, in newtons) of this rocket
  21.      */
  22.     public Rocket(String name, double mass, Dollars price, double apogee,
  23.             double thrust) {
  24.         super(name, mass, price);
  25.         setApogee(apogee);
  26.         setThrust(thrust);
  27.     }
  28.  
  29.     /**
  30.      * The height (in meters) that the rocket is expected to reach.
  31.      */
  32.     public double getApogee() {
  33.         return apogee;
  34.     }
  35.  
  36.     public void setApogee(double value) {
  37.         apogee = value;
  38.     }
  39.  
  40.     /**
  41.      * The rated thrust (or force, in newtons) of this rocket.
  42.      */
  43.     public double getThrust() {
  44.         return thrust;
  45.     }
  46.  
  47.     public void setThrust(double value) {
  48.         thrust = value;
  49.     }
  50. }

当然,getName() getPrice()这两个方法在超类Firework中定义。

posted on 2013-09-18 10:57  zjgtan  阅读(3529)  评论(0编辑  收藏  举报

导航