标识类型模式和常量接口模式
标识类型模式
定义一个不包含任何方法的接口,用它仅仅来表示一种抽象类型。所有实现该接口的类意味着属于这种类型。
比如定义一个Food接口,其中不包含任何方法:
public interface Food{}//实现该接口的类都是食物类型
鱼肉:
public class Fish implements Food{...}
进食方法:
public void eat(Food food){...}
进食:
Food fish = new Fish();//Fish实现了Food接口,标识其食物类型
eat(fish);//合法
Book book = new Book();//Book未实现Food接口
eat(book);//编译错误
所谓标识类型模式就是借助Java编译器来对传给eat()方法的food参数进行语义上的约束。Food接口被称为标识类型接口,这种接口没有任何方法,仅代表一种抽象类型。在JDK中,有如下两个典型的表示类型接口。
- java.io.Serializable接口:实现该接口的类的实例可以被序列化
- java.io.Remote接口:实现该接口的类的实例可以作为远程对象
常量接口模式
在一个软件系统中会使用一些常量,一种流行的做法是把相关的常量放在一个专门的常量接口中定义,例如:
package com.FinalInterface;
public interface MyConstants {
public static final double MATH_PI = 3.1415926;
public static final double MATH_E = 2.71828;
}
以下Circle类需要访问以上MATH_PI常量,一种方式是采用直接访问方式,如下:
package com.FinalInterface;
public class Circle {
private double r;//半径
public Circle(double r){
this.r = r;
}
public double getCircumference(){
return 2 * r * MyConstants.MATH_PI;
}
}
在JDK1.5中引入了”import static“语句,它允许类A直接访问另一个接口B或类B中的静态常量,而不必指定接口B或类B的名字,而且类A无须实现接口B或者继承类B。如下:
package com.FinalInterface;
import static com.FinalInterface.MyConstants.*;
public class Circle {
private double r;//半径
public Circle(double r){
this.r = r;
}
public double getCircumference(){
return 2 * r * MATH_PI;
}
}
import static 语句既可以简化编程,又能防止Circle类继承并公开MyConstants中的静态常量。
结合上我的上一篇:与接口相关的设计模式(1):定制服务模式和适配器模式详解,一共记录了与接口相关的5种设计模式,分别是定制服务模式、适配器模式、代理模式、标识类型模式以及常量接口模式。接口是构建松耦合的软件系统的重要法宝。接口的优势在于一个类可以实现多个接口,接口获得这一优势是以不允许为任何方法提供实现作为代价的(暂不考虑JAVA8的Default方法)。
我们可以把接口作为系统中最高层次的抽象类型。站在外界使用者(另一个系统)的角度,接口向使用者承诺系统能提供哪些服务;站在系统本身的角度,接口指定系统必须实现哪些服务。系统之间通过接口进行交互,这可以提高系统之间的松耦合。
至于抽象类呢,它用来定制系统中的扩展点。可以把抽象类看作介于”抽象“和”实现“之间的半成品。抽象类力所能及的完成了部分实现,但还有一些功能有待于它的子类去实现。