单例设计模式

  1. 单例设计模式的特点;
  2. 多例设计模式的特点。

单例设计模式

class Singleton{//编写一个普通类
	public void print(){
		System.out.println("www.mldn.cn");
	}
}

这个时候程序类给出后肯定是直接实例化对象,而后调用方法。

public class Hello{
	public static void main(String args[]){
		Singleton inst = null;//声明对象
		inst = new Singleton();//实例化对象
		inst.print();
	}
}

在这里插入图片描述
再次使得Singleton类中一定存在有无参构造方法,因为自动生成的。但是构造方法虽然一般都会使用public声明,可是也可以使用private声明。

class Singleton{//编写一个普通类
	private Singleton(){}//构造方法四私有了
	public void print(){
		System.out.println("www.mldn.cn");
	}
}
public class Hello{
	public static void main(String args[]){
		Singleton inst = null;//声明对象
		inst = new Singleton();//实例化对象
		inst.print();
	}
}

在这里插入图片描述
因为此时构造方法被私有化了,所以无法从外部进行构造方法的调用。现在在构造方法和print()方法没有做任何修改的情况下,做一些适当的Singleton变化让类外部可以得到Singleton类的实例化对象,并且调用print()方法。于是有了以下分析:
分析一:现在程序的关键是在于构造方法上使用了private(private Singleton(){}),那么对于private的特点只能够在本类中进行访问。那么现在换一个思路:能不能说在本类中准备好一个实例化对象呢?

class Singleton{//编写一个普通类
	Singleton instance = new Singleton();
	private Singleton(){}//构造方法四私有了
	public void print(){
		System.out.println("www.mldn.cn");
	}
}

分析二:此时内部声明的instance属性属于一个普通的属性,那么普通属性有一个前提:在实例化对象后才可以调用,但是现在外部类无法实例化对象,那么就考虑使用static,因为static不受到实例化控制。

class Singleton{//编写一个普通类
	static Singleton instance = new Singleton();
	private Singleton(){}//构造方法四私有了
	public void print(){
		System.out.println("www.mldn.cn");
	}
}
public class Hello{
	public static void main(String args[]){
		Singleton inst = null;//声明对象
		inst = Singleton.instance;//实例化对象
		inst.print();
	}
}

分析三:强调过只要是类中的属性都应该进行private封装,所以以上代码中的instance属性也应该进行封装,那么一旦封装了,就必须通过方法访问,那么此时要访问的是static属性,并且类无法直接在外部产生实例化对象,那么就编写一个static方法。

class Singleton{//编写一个普通类
	private static Singleton instance = new Singleton();
	private Singleton(){}//构造方法四私有了
	public static Singleton getInstance(){
		return instance;
	}
	public void print(){
		System.out.println("www.mldn.cn");
	}
}
public class Hello{
	public static void main(String args[]){
		Singleton inst = null;//声明对象
		inst = Singleton.getInstance();//实例化对象
		inst.print();
	}
}

分析四:这么写代码折腾一圈最终目的还是在外部使用实例化对象调用方法,意义在哪里?

public class Hello{
	public static void main(String args[]){
		Singleton instA = null;//声明对象
		Singleton instB = null;//声明对象
		Singleton instC = null;//声明对象
		instA = Singleton.getInstance();//实例化对象
		instB = Singleton.getInstance();
		instC = Singleton.getInstance();
		instA.print();
	}
}

在这里插入图片描述
通过内存关系可以发现,不管外部有多少个对象的声明,最终所产生的实例化对象只有一个。也就是说本程序限制了实例化对象的产生,只维持了一个。
之所以将构造方法私有就是切断了构造方法,那么自然无法产生新的实例化对象。
分析五:缺陷。为了保证整个代码在操作的过程中只会存在唯一的一个实例化对象,并且不可更改,则可以利用final声明。
面试题:请编写一个Singleton程序,并说明程序的主要特点

class Singleton{//编写一个普通类
	private static final Singleton INSTANCE = new Singleton();
	private Singleton(){}//构造方法四私有了
	public static Singleton getInstance(){
		return INSTANCE;
	}
	public void print(){
		System.out.println("www.mldn.cn");
	}
}
public class Hello{
	public static void main(String args[]){
		Singleton inst = null;//声明对象
		inst = Singleton.getInstance();
		inst.print();
	}
}

构造方法私有化,外部无法产生新的实例化对象,只能够通过类提供的static方法取唯一的一个对象的引用。
对于单例设计模式有两类:饿汉式(以上代码)、懒汉式。

  • 饿汉式:不管程序中是否有对象需要使用此类,此类的对象都要实例化好;
  • 懒汉式:在第一次使用的时候才进行实例化。
    范例:观察懒汉式
    class Singleton{//编写一个普通类
    	private static Singleton instance;
    	private Singleton(){}//构造方法四私有了
    	public static Singleton getInstance(){
    		if(instance==null){
    			instance = new Singleton();//需要的时候进行实例化
    		}
    		return instance;
    	}
    	public void print(){
    		System.out.println("www.mldn.cn");
    	}
    }
    public class Hello{
    	public static void main(String args[]){
    		Singleton inst = null;//声明对象
    		inst = Singleton.getInstance();
    		inst.print();
    	}
    }

这两个分类只是一个小小的概念,关键还是将之前的单例设计模式编写熟练。

多例设计模式

不管是单例设计还是多例设计,本质就一个:构造方法私有化,内部产生实例化对象,只不过单例设计只产生一个,多例设计会产生多个。
例如:现在要求描述一周时间数,只能够有七个对象;
例如:要求描述性别的类,只能有两个。
范例:性别的描述

class Sex{
	public static final int MALE_CH = 1;
	public static final int FEMALE_CH = 2;
	private static final Sex MALE = new Sex("男");
	private static final Sex FEMALE = new Sex("女");
	private String title;
	private Sex(String title){
		this.title=title;
	}
	public static Sex getInstance(int ch){
		switch(ch){
			case MALE_CH:
				return MALE;
			case FEMALE_CH:
				return FEMALE;
			default:
				return null;	
		}
	}
	public String toString(){
		return this.title;
	}
}
public class Hello{
	public static void main(String args[]){
		Sex sex = Sex.getInstance(Sex.MALE_CH);
		System.out.println(sex);
	}
}

多例只是单例的衍生品,本质上没有区别。

总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值