单例模式与多例模式的案例设计分析

 

Singleton and Multition Pattern单例模式与多例模式

目录

一、细说单例模式

1、单例模式的定义与特点 

2、模式的结构与实现 

      单例模式场景:  

           上代码: 

二、细说多例模式

       单例模式场景: 

             上代码: 


一、细说单例模式

1、单例模式的定义与特点

单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。

在计算机系统中,还有 Windows 的回收站、操作系统中的文件系统、多线程中的线程池、显卡的驱动程序对象、打印机的后台处理服务、应用程序的日志对象、数据库的连接池、网站的计数器、Web 应用的配置对象、应用程序中的对话框、系统中的缓存等常常被设计成单例。

单例模式有 3 个特点:

  1. 单例类只有一个实例对象;
  2. 该单例对象必须由单例类自行创建;
  3. 单例类对外提供一个访问该单例的全局访问点;

2、单例模式的结构与实现

单例模式是设计模式中最简单的模式之一。通常,普通类的构造函数是公有的,外部类可以通过“new 构造函数()”来生成多个实例。但是,如果将类的构造函数设为私有的,外部类就无法调用该构造函数,也就无法生成多个实例。这时该类自身必须定义一个静态私有实例,并向外提供一个静态的公有函数用于创建或获取该静态私有实例。

下面来分析其基本结构和实现方法。

单例模式场景: 

世界上只有一个月亮,月亮的直径是3476.28km,无论在中国还是在美国,我们所看到的都是同一个月亮。使用单例模式实现无论我们在哪所看到的月亮是同一个月亮(饿汉单例模式、懒汉单例模式),绘制类图并编程实现。

  •  

场景设计与实现

结构如图所示:

 

上代码

代码一

/*单例类*/

package com.rjs.singleton;
//懒汉模式
public class Mood {
	private static Mood mood=null;
	private static double distance=3476.28;
	private Mood() {
		System.out.println("产生一个月亮");
	}
	public static synchronized Mood getMood() {
		//在getMood方法上加上同步
		if(mood==null) {
			mood=new Mood();
		}else {
			System.out.println("已经产生了一个月亮,不能产生新的月亮!");
		}
		return mood;
	}
	public void getDistance() {
		System.out.println("我是月亮,我的直径是:"+distance+"km.");
	}
}

/*访问类*/
package com.rjs.singleton;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Mood americaMood=Mood.getMood();
		System.out.println("====我来自美国=====");
		americaMood.getDistance();
		System.out.println("====我来中国=====");
		Mood chinaMood=Mood.getMood();
		chinaMood.getDistance();
		
	}

}

    代码二:

二、细说多例模式

结合单例模式来说多例模式,单例模式相对来说比较容易理解一点,也就是在整个应用程序运行过程中,这个类的实例永远都是一个,好比如历朝历代,皇帝在大多数情况下都是只有一个,但是往往在程序运行过程中,我可能为了达到复用的效果,需要在一个池子中去选择对应的实例进行使用,这个时候多例模式也就应运而生了。

所谓多例模式其实也就是类的对象实例是有多个,但是这个多个也要区别于无限个,当然,如果一个类的对象可以有无限个的话,那能不能叫多例呢??这个可能就需要区别多例模式的特点了

所谓多例(Multiton Pattern)实际上就是单例模式的自然推广,属于对象
创建类型的模式,多例模式其实就是限制了对象的数量,并且有可能对对象进行重复使用

特点:
1:多例可以有多个实例
2: 多例类必须能够自我创建并管理自己的实例,并且向外界提供自己的实例

   多例模式场景:

在java学习过程中,有一个池子的概念一直存在,好比作线程池,数据库连接池,这个池子是用来对线程,或者数据库连接对象进行管理的,第一,限制了池子中的对象数量,第二就是能够在使用过程中达到复用的效果,线程中的线程在执行完毕后,不会被直接回收掉,而会切换成等待状态,等待下一个任务提交,执行。数据库连接池也是如此,数据库操作在连接的时候,如果对数据库操作完毕后,会把资源释放,然后等待下一个数据库操作进行连接。这种设计其实是将对象的应用最大化了,避免了每次连接的时候都需要去创建一个对象。造成对象冗余或者内存升高。

场景的设计与实现

结构如图所示:

             上代码: 

​
/*单例类*/

package com.rjs.singletonDataPool;

import java.util.ArrayList;
import java.util.Random;

public class SQLConnectionPools {
	private static int maxNumOfConnection= 3;
	private static ArrayList<String> connectionInfoList = new ArrayList<>(maxNumOfConnection);
	private static ArrayList<SQLConnectionPools> connArrayList = new ArrayList<>(maxNumOfConnection);
	private static int currNumOfConnection =0;
	
	private SQLConnectionPools() {
		// TODO Auto-generated constructor stub
	}
	
	private SQLConnectionPools(String info) {
		connectionInfoList.add(info);
	}
	
	static{
		for (int i = 0; i < maxNumOfConnection; i++) {
			connArrayList.add(new SQLConnectionPools(i+"号连接"));
		}
	}
	
	public static SQLConnectionPools getInstance() {
		Random random = new Random();
		currNumOfConnection = random.nextInt(maxNumOfConnection);
		return connArrayList.get(currNumOfConnection);
	}
	
	public void connectionInfo() {
		System.out.println(connectionInfoList.get(currNumOfConnection));
	}
	
}

/*访问类*/

package com.rjs.singletonDataPool;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		 int userNum=10;  
	        for(int i=0;i<userNum;i++){  
	            //用户获取到的连接时随机的  
	            SQLConnectionPools conn= SQLConnectionPools.getInstance();  
	            System.out.print("第"+i+"个用户获得的连接是:");  
	            conn.connectionInfo();  
	        }  
	}

}

​

参考:

单例模式(单例设计模式)详解

【设计模式九之多例模式】多例模式详解

猜你喜欢

转载自blog.csdn.net/qingxiao__123456789/article/details/105541276
今日推荐