论坛首页 Java企业应用论坛

设计模式之不变模式(Immutable Pattern)分析

浏览 16356 次
精华帖 (1) :: 良好帖 (10) :: 新手帖 (2) :: 隐藏帖 (1)
作者 正文
   发表时间:2011-03-15  
在多线程设计模式中,对该模式有全面的讲解
0 请登录后投票
   发表时间:2011-03-15  
nianien 写道
peterwei 写道
    一个类的实例的状态不会改变,同时它的子类的实例也具有不可变化的状态。这样的类符合强不变模式。要实现强不变模式,一个类必须首先满足弱不变模式所要求的所有条件,并且还要满足下面条件之一:
    第一,所考虑的类所有的方法都应当是final,这样这个类的子类不能够置换掉此类的方法。
    第二,这个类本身就是final的,那么这个类就不可能会有子类,从而也就不可能有被子类修改的问题。

为什么必须是final呢?私有属性,只读方法不也可以么?



只读有可能因为其他状态的改变,对应的也会变,比如说人的年龄的只读的,但是随着时间变化它是会变的
0 请登录后投票
   发表时间:2011-03-16  
gtssgtss 写道
private 一反射一下就被X了,怎么不变

你这真是强词夺理,按你那么说,我还可以动态改变JAVA CODE 去掉它的final属性,甚至类的定义,懂一点点反射,显摆啥啊
0 请登录后投票
   发表时间:2011-03-16   最后修改:2011-03-16
nianien 写道
gtssgtss 写道
private 一反射一下就被X了,怎么不变

你这真是强词夺理,按你那么说,我还可以动态改变JAVA CODE 去掉它的final属性,甚至类的定义,懂一点点反射,显摆啥啊

我的意思不是说反射。
我是说如果只是private,那么只是弱不变类。
    public static void main(String[] args) {   
        int state = 0;   
        User u = new User();   
        Integer age = 100;   
        u.setName("yes");   
        WeakImmutable weak = new WeakImmutable(state, u, age);   
        System.out.println("原始值:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
        // 修改引用后   
        state = 5;   
        // User由于是可变对象引用,所以有影响   
        u.setName("no");   
        age = 200;   
        System.out.println("修改引用后:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
    } 


结果:可以看到user的名字会改变。
原始值:0,yes,100
修改引用后:0,no,100

user在外部改变时,WeakImmutable里的private user属性因为是引用对实例对象,所以也跟着改变了。
0 请登录后投票
   发表时间:2011-03-17  
peterwei 写道
nianien 写道
gtssgtss 写道
private 一反射一下就被X了,怎么不变

你这真是强词夺理,按你那么说,我还可以动态改变JAVA CODE 去掉它的final属性,甚至类的定义,懂一点点反射,显摆啥啊

我的意思不是说反射。
我是说如果只是private,那么只是弱不变类。
    public static void main(String[] args) {   
        int state = 0;   
        User u = new User();   
        Integer age = 100;   
        u.setName("yes");   
        WeakImmutable weak = new WeakImmutable(state, u, age);   
        System.out.println("原始值:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
        // 修改引用后   
        state = 5;   
        // User由于是可变对象引用,所以有影响   
        u.setName("no");   
        age = 200;   
        System.out.println("修改引用后:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
    } 


结果:可以看到user的名字会改变。
原始值:0,yes,100
修改引用后:0,no,100

user在外部改变时,WeakImmutable里的private user属性因为是引用对实例对象,所以也跟着改变了。

我说的只读和你的不变类型一样有两成意思
这里,你对外开放的接口不要是User getUser(),而是改为String getUserName(){return user.getName()},这样不就可以了
我理解你的意思,只读的引用对象,其属性是可以改变的,而我的意思是,如果是引用对象,那么你就返回他的不可变的属性,而不要直接把对象返回
0 请登录后投票
   发表时间:2011-03-17  
nianien 写道
peterwei 写道
nianien 写道
gtssgtss 写道
private 一反射一下就被X了,怎么不变

你这真是强词夺理,按你那么说,我还可以动态改变JAVA CODE 去掉它的final属性,甚至类的定义,懂一点点反射,显摆啥啊

我的意思不是说反射。
我是说如果只是private,那么只是弱不变类。
    public static void main(String[] args) {   
        int state = 0;   
        User u = new User();   
        Integer age = 100;   
        u.setName("yes");   
        WeakImmutable weak = new WeakImmutable(state, u, age);   
        System.out.println("原始值:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
        // 修改引用后   
        state = 5;   
        // User由于是可变对象引用,所以有影响   
        u.setName("no");   
        age = 200;   
        System.out.println("修改引用后:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
    } 


结果:可以看到user的名字会改变。
原始值:0,yes,100
修改引用后:0,no,100

user在外部改变时,WeakImmutable里的private user属性因为是引用对实例对象,所以也跟着改变了。

我说的只读和你的不变类型一样有两成意思
这里,你对外开放的接口不要是User getUser(),而是改为String getUserName(){return user.getName()},这样不就可以了
我理解你的意思,只读的引用对象,其属性是可以改变的,而我的意思是,如果是引用对象,那么你就返回他的不可变的属性,而不要直接把对象返回


传入的时候,把参数clone,然后clone的对象赋值给field
传出的时候,再clone一次对象,这样就可以了。
0 请登录后投票
   发表时间:2011-03-17   最后修改:2011-03-17
nianien 写道
peterwei 写道
nianien 写道
gtssgtss 写道
private 一反射一下就被X了,怎么不变

你这真是强词夺理,按你那么说,我还可以动态改变JAVA CODE 去掉它的final属性,甚至类的定义,懂一点点反射,显摆啥啊

我的意思不是说反射。
我是说如果只是private,那么只是弱不变类。
    public static void main(String[] args) {   
        int state = 0;   
        User u = new User();   
        Integer age = 100;   
        u.setName("yes");   
        WeakImmutable weak = new WeakImmutable(state, u, age);   
        System.out.println("原始值:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
        // 修改引用后   
        state = 5;   
        // User由于是可变对象引用,所以有影响   
        u.setName("no");   
        age = 200;   
        System.out.println("修改引用后:" + weak.getState() + ","  
                + weak.getUser().getName() + "," + weak.getAge());   
    } 


结果:可以看到user的名字会改变。
原始值:0,yes,100
修改引用后:0,no,100

user在外部改变时,WeakImmutable里的private user属性因为是引用对实例对象,所以也跟着改变了。

我说的只读和你的不变类型一样有两成意思
这里,你对外开放的接口不要是User getUser(),而是改为String getUserName(){return user.getName()},这样不就可以了
我理解你的意思,只读的引用对象,其属性是可以改变的,而我的意思是,如果是引用对象,那么你就返回他的不可变的属性,而不要直接把对象返回

你占这个牛角尖干嘛呢。现在这个例子是弱不变类,我要想改成强不变类,我直接加上final不就完事了嘛。哪还要再加一个方法。你所说的对外再给一个普通属性的获取方法再封一层方法,这本来就不符合设计和重构的原则。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics