Singleton Pattern说, 只是“定义一个只有一个实例并提供对其全局访问点的类”。
换句话说, 一个类必须确保仅创建单个实例, 并且所有其他类都可以使用单个对象。
单例设计模式有两种形式
- 早期实例化:在加载时创建实例。
- 延迟实例化:在需要时创建实例。
Singleton设计模式的优势
- 因为没有在每个请求中创建对象, 所以节省了内存。只有单个实例一次又一次地被重用。
Singleton设计模式的用法
- 单例模式主要用于多线程和数据库应用程序。它用于日志记录, 缓存, 线程池, 配置设置等。
UML的Singleton设计模式
如何创建Singleton设计模式?
要创建单例类, 我们需要具有类的静态成员, 私有构造函数和静态工厂方法。
- 静态成员:由于静态, 它仅获取一次内存, 它包含Singleton类的实例。
- 私有构造函数:它将阻止从类外部实例化Singleton类。
- 静态工厂方法:此方法提供对Singleton对象的全局访问点, 并将实例返回给调用方。
了解Singleton模式的早期实例化
在这种情况下, 我们在声明静态数据成员时创建该类的实例, 因此该类的实例是在加载类时创建的。
让我们看一下使用早期实例化的单例设计模式的示例。
class A{
private static A obj=new A();//Early, instance will be created at load time
private A(){}
public static A getA(){
return obj;
}
public void doSomething(){
//write your code
}
}
了解单例模式的延迟实例化
在这种情况下, 我们将在同步方法或同步块中创建该类的实例, 因此将在需要时创建该类的实例。
让我们看一下使用延迟实例化的单例设计模式的简单示例。
class A{
private static A obj;
private A(){}
public static A getA(){
if (obj == null){
synchronized(Singleton.class){
if (obj == null){
obj = new Singleton();//instance will be created at request time
}
}
}
return obj;
}
public void doSomething(){
//write your code
}
}
类装载器在单例模式中的意义
如果单例类由两个类加载器加载, 则将创建两个单例类实例, 每个类加载器一个。
单例模式中序列化的意义
如果singleton类是Serializable, 则可以序列化singleton实例。序列化后, 你可以对其进行反序列化, 但不会返回单例对象。
若要解决此问题, 你需要重写强制执行单例的readResolve()方法。在对象反序列化之后立即调用它。它返回单例对象。
public class A implements Serializable {
//your code of singleton
protected Object readResolve() {
return getA();
}
}
了解单例模式的真实示例
- 我们将创建一个JDBCSingleton类。该JDBCSingleton类包含其构造函数(私有)和自身的私有静态实例jdbc。
- JDBCSingleton类提供了一个静态方法来将其静态实例传递给外界。现在, JDBCSingletonDemo类将使用JDBCSingleton类来获取JDBCSingleton对象。
假设:你创建了一个表userdata, 该表在mysql数据库中具有uid, uname和upassword三个字段。数据库名称是ashwinirajput, 用户名是root, 密码是ashwini。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
class JDBCSingleton {
//Step 1
// create a JDBCSingleton class.
//static member holds only one instance of the JDBCSingleton class.
private static JDBCSingleton jdbc;
//JDBCSingleton prevents the instantiation from any other class.
private JDBCSingleton() { }
//Now we are providing gloabal point of access.
public static JDBCSingleton getInstance() {
if (jdbc==null)
{
jdbc=new JDBCSingleton();
}
return jdbc;
}
// to get the connection from methods like insert, view etc.
private static Connection getConnection()throws ClassNotFoundException, SQLException
{
Connection con=null;
Class.forName("com.mysql.jdbc.Driver");
con= DriverManager.getConnection("jdbc:mysql://localhost:3306/ashwanirajput", "root", "ashwani");
return con;
}
//to insert the record into the database
public int insert(String name, String pass) throws SQLException
{
Connection c=null;
PreparedStatement ps=null;
int recordCounter=0;
try {
c=this.getConnection();
ps=c.prepareStatement("insert into userdata(uname, upassword)values(?, ?)");
ps.setString(1, name);
ps.setString(2, pass);
recordCounter=ps.executeUpdate();
} catch (Exception e) { e.printStackTrace(); } finally{
if (ps!=null){
ps.close();
}if(c!=null){
c.close();
}
}
return recordCounter;
}
//to view the data from the database
public void view(String name) throws SQLException
{
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con=this.getConnection();
ps=con.prepareStatement("select * from userdata where uname=?");
ps.setString(1, name);
rs=ps.executeQuery();
while (rs.next()) {
System.out.println("Name= "+rs.getString(2)+"\t"+"Paasword= "+rs.getString(3));
}
} catch (Exception e) { System.out.println(e);}
finally{
if(rs!=null){
rs.close();
}if (ps!=null){
ps.close();
}if(con!=null){
con.close();
}
}
}
// to update the password for the given username
public int update(String name, String password) throws SQLException {
Connection c=null;
PreparedStatement ps=null;
int recordCounter=0;
try {
c=this.getConnection();
ps=c.prepareStatement(" update userdata set upassword=? where uname='"+name+"' ");
ps.setString(1, password);
recordCounter=ps.executeUpdate();
} catch (Exception e) { e.printStackTrace(); } finally{
if (ps!=null){
ps.close();
}if(c!=null){
c.close();
}
}
return recordCounter;
}
// to delete the data from the database
public int delete(int userid) throws SQLException{
Connection c=null;
PreparedStatement ps=null;
int recordCounter=0;
try {
c=this.getConnection();
ps=c.prepareStatement(" delete from userdata where uid='"+userid+"' ");
recordCounter=ps.executeUpdate();
} catch (Exception e) { e.printStackTrace(); }
finally{
if (ps!=null){
ps.close();
}if(c!=null){
c.close();
}
}
return recordCounter;
}
}// End of JDBCSingleton class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
class JDBCSingletonDemo{
static int count=1;
static int choice;
public static void main(String[] args) throws IOException {
JDBCSingleton jdbc= JDBCSingleton.getInstance();
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
do{
System.out.println("DATABASE OPERATIONS");
System.out.println(" --------------------- ");
System.out.println(" 1. Insertion ");
System.out.println(" 2. View ");
System.out.println(" 3. Delete ");
System.out.println(" 4. Update ");
System.out.println(" 5. Exit ");
System.out.print("\n");
System.out.print("Please enter the choice what you want to perform in the database: ");
choice=Integer.parseInt(br.readLine());
switch(choice) {
case 1:{
System.out.print("Enter the username you want to insert data into the database: ");
String username=br.readLine();
System.out.print("Enter the password you want to insert data into the database: ");
String password=br.readLine();
try {
int i= jdbc.insert(username, password);
if (i>0) {
System.out.println((count++) + " Data has been inserted successfully");
}else{
System.out.println("Data has not been inserted ");
}
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}//End of case 1
break;
case 2:{
System.out.print("Enter the username : ");
String username=br.readLine();
try {
jdbc.view(username);
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}//End of case 2
break;
case 3:{
System.out.print("Enter the userid, you want to delete: ");
int userid=Integer.parseInt(br.readLine());
try {
int i= jdbc.delete(userid);
if (i>0) {
System.out.println((count++) + " Data has been deleted successfully");
}else{
System.out.println("Data has not been deleted");
}
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}//End of case 3
break;
case 4:{
System.out.print("Enter the username, you want to update: ");
String username=br.readLine();
System.out.print("Enter the new password ");
String password=br.readLine();
try {
int i= jdbc.update(username, password);
if (i>0) {
System.out.println((count++) + " Data has been updated successfully");
}
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Press Enter key to continue...");
System.in.read();
}// end of case 4
break;
default:
return;
}
} while (choice!=4);
}
}
评论前必须登录!
注册