无废话C#设计模式之二:Singleton

意图

保证一个类只有一个实例,并提供访问它的全局访问点。

场景

我们现在要做一个网络游戏的服务端程序,需要考虑怎么样才能承载大量的用户。在做WEB程序的时候有各种负载均衡的方案,不管是通过硬件实现还是软件实现,基本的思想就是有一个统一的入口,然后由它来分配用户到各个服务器上去。

需要考虑的问题是,即使在多线程的并发状态下,用户只能通过一个唯一的入口来分配,由此引入了Singleton模式来实现这个唯一的入口。

示例代码

using System;

using System.Collections.Generic;

using System.Threading;

namespace SingletonExample

{

    class Program

    {

        static void Main(string[] args)

        {

            ParameterizedThreadStart ts = new ParameterizedThreadStart(EnterPlayer);

            for (int i = 0; i < 20; i++)

            {

                Thread t = new Thread(ts);

                t.Start("player" + i);

            }

            LoadBalanceServer.GetLoadBalanceServer().ShowServerInfo();

        }

        static void EnterPlayer(object playerName)

        {

            LoadBalanceServer lbs = LoadBalanceServer.GetLoadBalanceServer();

            lbs.GetLobbyServer().EnterPlayer(playerName.ToString());

        }

    }

    class LoadBalanceServer

    {

        private const int SERVER_COUNT = 3;

        private List<LobbyServer> serverList = new List<LobbyServer>();

        private static volatile LoadBalanceServer lbs;

        private static object syncLock = new object();

        private LoadBalanceServer()

        {

            for (int i = 0; i < SERVER_COUNT; i++)

            {

                serverList.Add(new LobbyServer("LobbyServer" + i));

            }

        }

        public static LoadBalanceServer GetLoadBalanceServer()

        {

            if (lbs == null )

            {

                lock (syncLock)

                {

                    if (lbs == null )

                    {

                        Thread.Sleep(100);

                        lbs = new LoadBalanceServer();

                    }

                }

            }

            return lbs;

        }

        public LobbyServer GetLobbyServer()

        {

            LobbyServer ls = serverList[0];

            for (int i = 1; i < SERVER_COUNT; i++)

            {

                if (serverList[i].PlayerList.Count < ls.PlayerList.Count)

                    ls = serverList[i];

            }

            return ls;

        }

        public void ShowServerInfo()

        {

            foreach (LobbyServer ls in serverList)

            {

                Console.WriteLine("=================" + ls.ServerName + "=================");

                foreach (string player in ls.PlayerList)

                {

                    Console.WriteLine(player);

                }

            }

        }

    }

    class LobbyServer

    {

        private List<string> playerList = new List<string>();

        public List<string> PlayerList

        {

            get { return playerList; }

        }

        private string serverName;

        public string ServerName

        {

            get { return serverName; }

        }

        public LobbyServer(string serverName)

        {

            this.serverName = serverName;

        }

        public void EnterPlayer(string playerName)

        {

            playerList.Add(playerName);

        }

    }

}

时间: 2024-08-19 08:30:19

无废话C#设计模式之二:Singleton的相关文章

无废话C#设计模式之二十二:总结(针对GOF23)

本文配套源码 比较 设计模式 常用程度 适用层次 引入时机 结构复杂度 Abstract Factory 比较常用 应用级 设计时 比较复杂 Builder 一般 代码级 编码时 一般 Factory Method 很常用 代码级 编码时 简单 Prototype 不太常用 应用级 编码时.重构时 比较简单 Singleton 很常用 代码级.应用级 设计时.编码时 简单 Adapter 一般 代码级 重构时 一般 Bridge 一般 代码级 设计时.编码时 一般 Composite 比较常用

无废话C#设计模式之二十一:Visitor

意图 实现通过统一的接口访问不同类型元素的操作,并且通过这个接口可以增加新的操作而不改变元素的类. 场景 想不出什么好例子,我们在组合模式的那个例子上进行修改吧.我们知道,无论是游戏大区.游戏服务器还是游戏的服务都是一个元素,只不过它们的层次不一样.对于这样的层次结构,我们使用了组合模式来统一各层的接口,这样对游戏大区的操作和对游戏服务器的操作对调用方来说没有什么两样.在现实中,组合模式的运用往往没有这么顺利: l 如果元素需要增加新的操作,那么势必需要在抽象元素中增加接口,这个时候的改动就非常

无废话C#设计模式之二十:Mediator

意图 用一个中介对象来封装一系列对象的交互.中介者使得各对象不需要显式相互引用,从而使其松散耦合,而且可以独立地改变它们之间的交互. 场景 我们知道,一个网络游戏往往有很多大区.每一个大区可以是一组服务器,也可以是多组服务器,在这里假设一个大区是一组服务器.为了效率,一般每个大区都会有一个数据库,玩家的创建角色.充值.消费行为只是在这一个大区中有效.现在公司有了新的需求,那就是玩家的一些信息能在多个大区中共享.比如,在注册的时候就把玩家的账户信息写入多个信息共享的大区,玩家在某个大区中充值需要"

无废话C#设计模式之十二:Bridge

意图 将抽象部分与实现部分分离,使它们都可以独立的变化. 场景 还是说我们要做的网络游戏,多个场景需要扩充的问题我们已经采用了创建型模式来解决.现在的问题就是,不仅仅是游戏场景会不断扩充,而且游戏的模式也在不断扩充.比如,除了最基本的战斗模式之外,还会有道具模式,金币模式等. 对于这种在多个维度上都会有变化或扩充需求的项目来说,可以考虑引入桥接模式.或许你会说,不管是什么场景,不管什么模式,都可以是抽象场景的一个子类,但是,如果这样的话,4个场景和3种模式就会产生12个子类,而10个场景5种模式

无废话C#设计模式之五:Prototype

意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 场景 游戏场景中的有很多相似的敌人,它们的技能都一样,但是随着敌人出现的位置不同,这些人的能力不太一样.假设,我们现在需要把三个步兵组成一队,其中还有一个精英步兵,能力特别高.那么,你或许可以创建一个敌人抽象类,然后对于不同能力的步兵创建不同的子类.然后,使用工厂方法等设计模式让调用方依赖敌人抽象类. 问题来了,如果有无数种能力不同步兵,难道需要创建无数子类吗?还有,步兵模型的初始化工作是非常耗时的,创建这么多步兵对象可能还

无废话C#设计模式之三:Abstract Factory

意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 场景 还是上次说的那个网络游戏,定下来是一个休闲的FPS游戏.和CS差不多,8到16个玩家在游戏里面分成2组对战射击.现在要实现初始化场景的工作.要呈现一个三维物体一般两个元素是少不了的,一是这个物体的骨架,也就是模型,二就是这个骨架上填充的纹理. 我们知道,这样的一个游戏不可能只有一张地图,而且地图的数量肯定是会一直增加的.如果游戏在初始化场景的时候需要根据不同的地图分别加载模型和纹理对象,那么势必就会使得场景的扩充变

无废话C#设计模式之一:开篇

什么是设计模式? 什么是少林拳呢?少林拳是少林僧人经过长期的总结,得出的一套武功套路.有一本叫做少林拳法的武功秘籍,上面记载这这套拳法的适用人群,打法套路和学成后的效果.设计模式虽然记录在了设计模式一书上,但是要真正掌握设计模式光靠看每一个模式的结构并且进行模仿是不够的.试想一下,在真枪实战的情况下,谁会和你按照少林拳法,一二三四的套路打呢?打套路也只能用来看看,只有当你能根据不同的场景灵活出招的时候才能说是学会了这套拳法.相似的例子还有三十六计,这也是一种模式,每种计谋都是针对不同场景的,如果

无废话C#设计模式之十五:Strategy

意图 定义一系列的算法,把它们一个一个封装起来,并且使它们可相互替换.本模式使得算法可以独立于它的客户而变化. 场景 在开发程序的时候,我们经常会根据环境不同采取不同的算法对对象进行处理.比如,在一个新闻列表页面需要显示所有新闻,而在一个新闻搜索页面需要根据搜索关键词显示匹配的新闻.如果在新闻类内部有一个ShowData方法的话,那么我们可能会传入一个searchWord的参数,并且在方法内判断如果参数为空则显示所有新闻,如果参数不为空则进行搜索.如果还有分页的需求,那么还可能在方法内判断是否分

无废话C#设计模式之十四:Template Method

意图 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 场景 模版方法是非常容易理解的设计模式,一来是因为它没有过多结构上的交错,二来是因为这种代码复用技术对于掌握OO知识的人来说非常容易可以想到,很可能你已经在很多地方运用了模版方法.在运用一些设计模式的时候常常也会一起运用模版方法,甚至有的设计模式本身就带有模版方法的思想. 今天,我们给出这样一个实际的例子.做过银行支付.支付宝支付的人都知道,