黑马程序员技术交流社区

标题: 设计模式---<<单例设计模式>> [打印本页]

作者: 杨增坤    时间: 2013-9-5 12:03
标题: 设计模式---<<单例设计模式>>
本帖最后由 杨增坤 于 2013-9-5 19:35 编辑

在总结单例设计模式的时候遇到的疑问。
  把实例化的对象定义成公有的且静态的后,这样就可以不用使用方法来返回,这样也可以防止多线程出现异常,就可以用类名直接调用了。这样不就更方便呢啊!
  
public class Single {
  
  public static Single s = new Single();
  
  private Single() {}
  
}
  
public class SingleDemo {
  
  public static void main(String[] args) {
  
       Single s1=Single.s;        
  
  }
  
}
  


难道这是那是写代码的习惯??那样写更符合写程序的规则吗??是这样理解?

作者: 昝文萌    时间: 2013-9-5 12:23
这样的话你在主函数里多次调用Single.s的话,会创建多个对象!
  1. public class SingleDemo {
  2.   
  3.   public static void main(String[] args) {
  4.   
  5.        Single s1=Single.s;//创建对象s1
  6.        Single s2=Single.s;//创建对象s2   
  7.   
  8.   }
  9.   
  10. }
复制代码

作者: gulup    时间: 2013-9-5 12:43
二楼的说法不对,重复引用s是不会重复创建对象的,静态代码,在类首次被加载到虚拟机中时,就会被分配到内存空间,切指挥执行一次。而后,根本就没有机会再次调用到new Single();所以不会重复创建对象。
至于楼主的问题。其实你的写法没有错,但是,思想不对。
因为Java是面向对象的语言。程序的设计因该遵循面向对象的思想。面向对象的额特征之一,封装。
类中的属性都应该进行封装,Single s是Single类中的属性,应该对其进行封装。并对外提供一个方法使外部能对其调用。
所以说,楼主的写法没有错。但是不应该这么写
作者: javamov    时间: 2013-9-5 13:00
java类中的成员变量都暴露了,不安全。饿汉式比较占用内存空间。
线程是安全的,但不体现java的封装性。{:soso_e113:}
作者: 夏天那抹蓝╮    时间: 2013-9-5 13:00
假设single有子类的话,那我执行
Single.s = new SubSingle();
不就把那个改了。

其实设计模式更多的是语义上的。而不是语法上的,怎么实现并不重要,重要的是一个类只有一个对象这个语义。
以后用了spring就不用这样来设计了,全都是用配置文件来配置了。配置单例还是多例。
作者: 杨增坤    时间: 2013-9-5 13:41
昝文萌 发表于 2013-9-5 12:23
这样的话你在主函数里多次调用Single.s的话,会创建多个对象!

public class Single {
        public static Single s = new Single();
        private String name="张三";
        private Single() {}
        public static Single getS() {
                return s;
        }
        public static void setS(Single s) {
                Single.s = s;
        }
        public String getName() {
                return name;
        }
        public void setName(String name) {
                this.name = name;
        }       
       
}
public class SingleDemo {       
        public static void main(String[] args) {
            Single s1=Single.s;               
            System.out.println(s1.getName());
            Single s2=Single.s;
            s2.setName("李四");
            System.out.println(s2.getName());//李四
            System.out.println(s1.getName());//李四
        }
}

但是结构她们还是同一个对象的,而不是多个对象不一样,和用方法执行结果是一样的,



作者: 杨增坤    时间: 2013-9-5 13:45
夏天那抹蓝╮ 发表于 2013-9-5 13:00
假设single有子类的话,那我执行
Single.s = new SubSingle();
不就把那个改了。

我的那个Single类的构造方法是私有的,他是不可以继承的,不可能有子类,所以你的说法是不正确的吧!

作者: 神之梦    时间: 2013-9-5 21:58
Single.s=null;
作者: 杨增坤    时间: 2013-9-5 22:32
神之梦 发表于 2013-9-5 21:58
Single.s=null;

我明白了,懂了,如果这样写的话,就能够设置单例中的对象,那么就把对象暴露了是吧!
说到点子上了!

作者: hmwudizl91zl    时间: 2013-9-8 08:25
不对吧,你应该把类的构造方法设置成私有的,因为单例模式不能被类外的创建对象,需要加上private,其中static是为了让你的对象只创建一次,看看我说的对不
作者: 张文豪    时间: 2013-9-8 09:19
杨增坤 发表于 2013-9-5 22:32
我明白了,懂了,如果这样写的话,就能够设置单例中的对象,那么就把对象暴露了是吧!
说到点子上了!
...

为什么说写Single.s=null,就能够设置单例中的对象,就把对象暴露了呢??  求详细解答。
是说Single s1=Single.s,因为s为nul,所以s1也为null,这样就能够设置单例中的对象?



作者: 杨增坤    时间: 2013-9-8 10:58
张文豪 发表于 2013-9-8 09:19
为什么说写Single.s=null,就能够设置单例中的对象,就把对象暴露了呢??  求详细解答。
是说Single s1= ...

因为Slinge.s可以为他重新赋值,但是用public Slnge getInsance的话,那么获取出来的对象,虽然也可以重新赋值,再次获取的话,还是原来的值,没哟被覆盖,但是用 Slinge.s,就会覆盖 的。


作者: 杨增坤    时间: 2013-9-8 11:00
hmwudizl91zl 发表于 2013-9-8 08:25
不对吧,你应该把类的构造方法设置成私有的,因为单例模式不能被类外的创建对象,需要加上private,其中stat ...

但是这样的话,可以呗重新赋值,会覆盖原来的值,如果用方法的话,只有获取的,没有赋值的方法,所以更要全的!





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2