1、Immutable interface(不可变接口)
假设你有一个表示圆圈的mutable class MutableCirle, 你想把它变成immutable object。
class MutableCircle{
private double radius;
public MutableCircle(double r){
radius = r;
}
public void setRadius(double r){
radius = r;
}
public double radius(){
return radius;
}
}
为了让这个class成为一个immutable class, 你可以声明一个immutable interface再由这个class去实现它。如:
interface ImmutableCircle{
public double radius();
}
class MutableCircle implements ImmutableCircle{
private double radius;
public MutableCircle(double r){
radius = r;
}
public void setRadius(double s){
radius = r;
}
public double radius(){
return radius;
}
}
由于immutable interface仅仅暴露底部class的non-mutating methods,可以通过这个interface访问的objects能保持不变性。
ImmutableCircle iwheel = new MutableCircle(6);
这种方法隐藏了setRadius方法。但是他人还是可以通过cast到MutableCircle去调用setRadius。
2、公共接口或公共基类
定义一个公用的接口或基类,然后在实现两个subclass 一个是mutable 一个immutable。
如:
interface PinNumbers{
public String accountOwner();
public int checkingPin();
public int savingsPin();
}
class MutablePinNumbers implements PinNumbers{
private String acctOwner;
private int checkingAcctPin;
private int savingAcctPin;
MutablePinNumbers(String owner,int cPin,int sPin){
acctOwner = owner;
checkingAccPin = cPin;
savingsAcctPin = sPin;
}
// 下面提供mutable函数实现代码。
pubic void setAccountOwner(String str){
acctOwner = str;
}
// 下面是每个field的getter// setter方法。
}
final class ImmutablePinNumbers implements PinNumbers{
private String acctOwner;
private int checkingAcctPin;
private int savingAcctPin;
ImmutablePinNumbers(String owner,int cPin,int sPin){
acctOwner = owner;
checkingAccPin = cPin;
savingsAcctPin = sPin;
}
// all fields getter method
}
3、不可变的委托类(immutable Delegation Class)
其实是复合的实现方式,将外界对他们的调用任务委托(delegates)给class内含的mutable object。 如:
上面的circle classes可以实现为。
class MutableCircle{
private double radius;
public MutableCircle(double r){
radius = r;
}
public void setRadius(double r){
radius = r;
}
public double radius(){
return radius;
}
}
final class ImmutableCircle{
private MutableCircle mCircle;
public ImmutableCircle(){
mCircle = new MutableCircle(r);
}
public double radius(){
return mCircle.radius();
}
}
书上说这种方式要以性能为代价, 我觉得这种实现更优秀, effective java 中说过 复合优与继承。
*所说的性能可能是表面上是immutable类但是实际上内部还是mutable类 所有性能代价更大。