欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-14 22:54:52
...

 

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();  
	        }  
	}

}

​

参考:

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

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