单例和多例设计模式
(一)、单例模式
问题:如果说现在只希望一个类只能够产生唯一的一个实例化对象,该怎么办?
唯一的解决办法是控制构造方法,所有的对象实例化的时候一定会调用类中的构造方法,如果构造方法不能使用了,那么就表示外部无法实例化对象,可问题是每一个类中都有构造方法。
这个时候可以利用private声明构造方法,private的特点是只能在类的类的内部访问,所以如果构造方法上使用了private,就表示这个构造方法外部不能使用了。
如下:
class Singleton{ //构造方法被私有化 private Singleton(){ } public void print(){ System.out.println("Hello,World!"); } } public class TestDemo { public static void main(String[] args) { // TODO Auto-generated method stub Singleton singleton=null; //声明对象 singleton =new Singleton(); //实例化对象 } }
这个时候会出错,使外部无法直接使用构造方法,如下图:
虽然现在至少可以控制对象的产生,但问题是,现在我们要怎么去使用呢?既然外部无法产生,那么怎么在内部去产生呢?
这个时候试着去Singleton内部去实例化一个对象
class Singleton{ //实例化对象 Singleton instance=new Singleton(); //构造方法被私有化 private Singleton(){ } public void print(){ System.out.println("Hello,World!"); } }
既然现在已经有了一个内部的实例化对象,那么想办法把它拿到外部来就好,注意,它是一个普通的属性,普通属性只有在类产生实例化对象的时候才可以调用,那么现在问题来了,有没有一种方法可以在不产生实例化对象的情况下依然可以使用类中的属性呢?这个时候可以利用static来完成。如下:
package model; class Singleton{ //实例化对象 static Singleton instance=new Singleton(); //构造方法被私有化 private Singleton(){ } public void print(){ System.out.println("Hello,World!"); } } public class TestDemo { public static void main(String[] args) { // TODO Auto-generated method stub Singleton singleton=null; //声明对象 //singleton =new Singleton(); //实例化对象 singleton=Singleton.instance; singleton.print(); } }
这个时候就可以看到控制正常的打印出“Hello,world!”,
利用static定义的为全局变量,也就是说不管外部怎么去操作,它永远都只有一个static定义的instance属性。即只会产生一个实例化对象,但以上的代码不标准,要加上对象的封装操作。如下:
package model; class Singleton{ //实例化对象 private static Singleton instance=new Singleton(); public static Singleton getSingleton(){ return instance; } //构造方法被私有化 private Singleton(){ } public void print(){ System.out.println("Hello,World!"); } } public class TestDemo { public static void main(String[] args) { // TODO Auto-generated method stub Singleton singleton=null; //声明对象 //singleton =new Singleton(); //实例化对象 singleton=Singleton.getSingleton(); singleton.print(); } }
但以上的代码还有一点不太好,没有突出唯一性,即指对象不能再进行实例化了。比如,修改一下Singleton类中的getSingleton方法如下:
public static Singleton getSingleton(){ instance=new Singleton(); return instance; }
这就表示每次取走一个instance,你都会实例化一个新的对象,运行结果发现可以顺利执行,但这与我们的“单例”就矛盾了,明显不对。这个时候关键的“final”( 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义)就可以起到作用了。
private static final Singleton INSTANCE=new Singleton();
这个时候就会发现我们前面写的东西就会出错,不允许我们再次的去实例化对象
(二)、多例模式
除了单例模式之外还有多例设计模式,若果说单例设计模式只能有一个实例化对象,那么多例就有可以有多个实例化对象,相当于定义了类中对象的个数。比如说现在要定义一个星期时间数的类,那么他的对象只需要七个(天),再比如现在要写一个表示颜色基色的类,那么它的对象就只需要三个。
案例:
多例模式:写一个表示人的性别的类,即只能有两个实例对象,或男或女。
package model; class Sex{ private static final Sex MALE=new Sex("男"); private static final Sex FEMALE=new Sex("女"); private String title; public Sex(String title) { this.title=title; } public String getTitle() { return this.title; } public static Sex getSex(int ch){ switch (ch) { case 1:{ return MALE; } case 2:{ return FEMALE; } default: return null; } } } public class Multiton { public static void main(String[] args) { // TODO Auto-generated method stub Sex mySex=Sex.getSex(1); System.out.println(mySex.getTitle()); } }
主题思想摘自李兴华的设计模式视频讲解