세부 디자인 패턴: 싱글톤 패턴

이 기사에서는 생성 모드에서 세 번째로 가장 일반적으로 사용되는 모드인 싱글톤 모드를 살펴봅니다. 그래도 두 장의 사진을 먼저 보고, 모드 종류를 복습하고, 기억을 더 깊게 하는 것이다.

정의:

싱글톤 모드: 클래스에 인스턴스가 하나만 있는지 확인하고 이 고유한 인스턴스에 액세스할 수 있는 전역 액세스 지점을 제공합니다 .

싱글톤 패턴: 클래스에 인스턴스가 하나만 있는지 확인 하고 글로벌 액세스 지점을 제공합니다.

주요 요점:

클래스는 하나의 인스턴스만 가질 수 있습니다.

이 인스턴스를 직접 만들어야 합니다.

이 인스턴스를 전체 시스템 자체에 제공 해야 합니다.

가장 간단한 실제 사례는 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; 
    }
}

클래스 다이어그램:

적용 가능성:

시스템에 하나의 인스턴스 객체만 필요하거나 너무 많은 리소스 소비로 인해 하나의 객체만 생성할 수 있습니다.
클라이언트 호출 클래스의 단일 인스턴스는 하나의 공용 액세스 포인트만 사용할 수 있으며 공용 액세스 포인트 이외의 다른 수단을 통해 인스턴스에 액세스할 수 없습니다.

이점:

고유한 인스턴스에 대한 제어된 액세스 제공
시스템 리소스를 절약 하고 시스템 성능을 향상시킬 수 있습니다.
가변 개수의 인스턴스 허용( 여러 인스턴스 클래스 )

결점:

확장 어려움 (추상화 계층 부족)
Singleton 클래스에는 너무 많은 책임이 있습니다.
자동 가비지 수집 메커니즘으로 인해 공유 싱글톤 개체의 상태가 손실 될 수 있습니다.


사례 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