设计模式详解:单例模式

本篇来看一下创建型模式中最常用的第三种模式:单例模式。仍然是先看两张图,复习模式类型,加深记忆。

定义:

单例模式:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例

Singleton Pattern: Ensure a class has only one instance, and provide a global point of access to it.

要点:

某个类只能有一个实例

必须自行创建这个实例

必须自行向整个系统提供这个实例

最简单的实用案例就是windows操作系统中的任务管理器,还有负载均衡的唯一性等。

结构:

分类:

饿汉式单例类:无须考虑多个线程同时访问的问题;调用速度和反应时间优于懒汉式单例;资源利用效率不及懒汉式单例;系统加载时间可能会比较长

class EagerSingleton 
{ 
    private static EagerSingleton instance = new EagerSingleton(); 
    private EagerSingleton() { } 
    public static EagerSingleton GetInstance() 
    {
        return instance; 
    }
}

懒汉式单例类:实现了延迟加载;必须处理好多个线程同时访问的问题;需通过双重检查锁定等机制进行控制,将导致系统性能受到一定影响

class Singleton 
{
    private static Singleton instance=null;  
    private Singleton()
    {	
    }
	
    public static Singleton GetInstance() 
    {
        if(instance==null)
            instance=new Singleton();	
        return instance;
    }
}

懒汉式防止不同进程重复调用,可以双重检查锁定:


class LazySingleton 
{ 
    private static LazySingleton instance = null; 

    //程序运行时创建一个静态只读的辅助对象
    private static readonly object syncRoot = new object();

    private LazySingleton() { } 

    public static LazySingleton GetInstance() 
    { 
        //第一重判断,先判断实例是否存在,不存在再加锁处理
        if (instance == null) 
        {
            //加锁的程序在某一时刻只允许一个线程访问
            lock(syncRoot)
            {
                //第二重判断
                if(instance==null)
                {
                    instance = new LazySingleton();  //创建单例实例
                }
            }
        }
        return instance; 
    }
}

类图:

适用性:

系统 只需要一个实例对象 ,或者因为资源消耗太大而 只允许创建一个对象
客户调用类的单个实例 只允许使用一个公共访问点 ,除了该公共访问点,不能通过其他途径访问该实例

优点:

提供了 对唯一实例的受控访问
可以 节约系统资源 提高系统的性能
允许可变数目的实例( 多例类

缺点:

扩展困难 (缺少抽象层)
单例类的 职责过重
由于自动垃圾回收机制,可能会导致共享的单例对象的 状态丢失


案例1:(.NET代码)

using System;

namespace SingletonSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建四个LoadBalancer对象
		    LoadBalancer balancer1,balancer2,balancer3,balancer4;
		    balancer1 = LoadBalancer.GetLoadBalancer();
		    balancer2 = LoadBalancer.GetLoadBalancer();
		    balancer3 = LoadBalancer.GetLoadBalancer();
		    balancer4 = LoadBalancer.GetLoadBalancer();
		
		    //判断服务器负载均衡器是否相同
		    if (balancer1 == balancer2 && balancer2 == balancer3 && balancer3 == balancer4) 
            {
			    Console.WriteLine("服务器负载均衡器具有唯一性!");
		    }
		
		    //增加服务器
		    balancer1.AddServer("Server 1");
		    balancer1.AddServer("Server 2");
		    balancer1.AddServer("Server 3");
		    balancer1.AddServer("Server 4");

            //模拟客户端请求的分发,如果输出结果全为同一个server,可以将i适当放大,例如改为"i < 100"
		    for (int i = 0; i < 10; i++) 
            {
                string server = balancer1.GetServer();
                Console.WriteLine("分发请求至服务器: " + server);
            }
            Console.Read();
        }
    }
}
using System;
using System.Collections;

namespace SingletonSample
{
    class LoadBalancer
    {
        //私有静态成员变量,存储唯一实例
        private static LoadBalancer instance = null;
        //服务器集合
        private ArrayList serverList = null;

        //私有构造函数
        private LoadBalancer()
        {
            serverList = new ArrayList();
        }

        //公有静态成员方法,返回唯一实例
        public static LoadBalancer GetLoadBalancer()
        {
            if (instance == null)
            {
                instance = new LoadBalancer();
            }
            return instance;
        }

        //增加服务器
        public void AddServer(string server)
        {
            serverList.Add(server);
        }

        //删除服务器
        public void RemoveServer(string server)
        {
            serverList.Remove(server);
        }

        //使用Random类随机获取服务器
        public string GetServer()
        {
            Random random = new Random();
            int i = random.Next(serverList.Count);
            return serverList[i].ToString();
        }
    }
}

案例2:(JAVA代码)

public class Singleton {
    
    private static Singleton sing;

    private Singleton() {
        
    }
    
    public static Singleton getInstance() {
        if (sing == null) {
            sing = new Singleton();
        }
        return sing;
    }
}
public class Test {
    
    public static void main(string[] args) {
        Singleton sing = Singleton.getInstance();
        Singleton sing2 = Singleton.getInstance();
        
        System.out.println(sing);
        System.out.println(sing2);
    }
}

猜你喜欢

转载自blog.csdn.net/daobaqin/article/details/127712899
今日推荐