尝试从技术的角度回到你的问题,不知道能否对你有帮助。
按照你描述的场景,依我的推断,这个“业务配置”(ServiceInfo)应该是系统初始化之后就不能改动的一个全局变量,也就是一个系统常量吧。
对于系统常量,当然不能供外界随便修改,这可能会出现安全漏洞,甚至导致系统崩溃。
而你的解决方案,正如你自己的分析,通过“拷贝”对象保持原有对象的“非可变性”,这从技术的角度是合理的设计,这叫“保护性拷贝”,但这样就出现了对象数量大大增加,浪费内存的后果。可以说,“保护性拷贝”是某种场合下的合理和安全的设计,但并不适合你的应用场景。因为你的ServiceInfo是全局性的,不应该让每个线程拥有一份。
面对这样的场景,不能使用数组或者HashTable去保存你的系统信息常量,因为数组和可变的Collection都无法保证其不可变性(参考《Effective Java》)
所以,只能以常量去定义你的多个ServiceInfo,代码示例如下:
public class ServcieInfo {
private String member1;
private String member2;
public static final SYSTEM_SERVICE_INFO_1; //业务配置1
public static final SYSTEM_SERVICE_INFO_2; //业务配置2
...
public static final SYSTEM_SERVICE_INFO_N; //业务配置N
static {
// 如果你的业务配置需要从外部设置(例如从Properties文件或XML文件),则在这个静态块里面完成SYSTEM_SERVICE_INFO_N的实例化
}
public String getMember1() {
return member1;
}
public String getMember2() {
return member2;
}
private void setMember1(String member1) {
this.member1=member1;
}
private void setMember2(String member2) {
this.member2=member2;
}
private ServiceInfo(String member1,String member2) {
this.member1=member1;
this.member2=member2;
}
}
说明:
1.不允许外界对ServiceInfo的成员变量作任何修改,因此成员变量需要定义为private,并且不提供public的setter方法
2.让ServiceInfo的构造函数私有化,从而保证了外界无法轻易“伪造”(为什么是“轻易”,因为外界还是可以通过反射机制“伪造”)
3.让各个ServiceInfo声明为public static final常量,外界无法修改它的“引用”(Reference)
4.这里只对ServiceInfo的定义进行了示例,如果你的ServiceInfo有其他类型的成员变量(比如自定义类型),千万千万要记住,把这些成员变量设计为“非可变对象”(Immutable Object)
这样,外界只能通过 ServiceInfo.SYSTEM_SERVICE_INFO_N使用你的业务配置信息,他们没法修改你的业务配置信息,也无法创建,同时无法改变你的常量的引用,即使外界通过getter方法获得了ServiceInfo的成员变量的实例并进行“恶意”修改,由于你的成员变量是“非可变“的,他们的修改也不会影响你的全局业务配置
[该贴被johnnylzb于2008-02-21 17:25修改过]
[该贴被johnnylzb于2008-02-21 17:27修改过]