设计模式简介
1.解决共通的问题
2.归纳相同的解决方案
3.类结构和组装方式
4.高复用度与组合使用
单例模式
1.what
单例模式:
该模式只涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。该类提供了一种访问其唯一对象的方式,可以直接访问,不需要实例化类对象。
特点:
单例类只能有一个实例;
单例类必须自己创建自己的唯一实例;
单例类必须给所有的其它对象提供这一实例;
可以快速获取实例对象提供的方法或服务;
适合游戏场景中单一功能的管理器。
2.when
使用场景:
开发时需要控制实例数目,节省系统资源时。比如UI管理器、声音管理器、网络管理器等,有且只有一个实例,有且需要一个实例。
3.how
{
//第一种方式
public static Singleton _instance;
private void Awake()
{
_instance = this;
}
//单例提供的公共方法
public void SayHello()
{
Debug.LogError("I am" + name);
}
//缺点:这种方式必须在场景中创建挂载该单例组件的游戏物体,否者会出现空引用的错误。
public class Singleton:MonoBehaviour
//第二种方式
static Singleton instance;
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType<Singleton>();
}
if (instance == null)
{
GameObject obj = new GameObject();
obj.AddComponent<Singleton>();
instance = obj.GetComponent<Singleton>();
}
return instance;
}
}
//优点:弥补了第一种单例模式的不足,但是复用性不够
当我们使用线程的时候,效率最高的方式当然是异步,即个个线程同时运行,其间互不依赖和等待。当不同的线程都需要访问某个资源的时候,就需要同步机制了,也就是说当对同一个资源进行读写的时候,我们要使该资源在同一时刻只能被同一个线程操作,以确保每个操作都是有效即时的,也即保证其操作的原子性。
lock是C#中最常用的同步方式,格式为lock(objectA){codeB} 。
lock(objectA){codeB}表示意义:
1. objectA被lock了吗?没有则由我来lock,否则一直等待,直至objectA被释放。
2. lock以后在执行codeB的期间其他线程不能调用codeB,也不能使用objectA。
3. 执行完codeB之后释放objectA,并且codeB可以被其他线程访问。
public class WeiHaiSingleTon<T> : MonoBehaviour
where T : Component
{
private static volatile T _instance;
//设置静态锁
private static object _instanceLock = new object();
public static T Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType(typeof(T)) as T;
lock (_instanceLock)
{
if (_instance == null)
{
GameObject obj = new GameObject();
//隐藏实例化的对象
obj.hideFlags = HideFlags.HideAndDontSave;
_instance = obj.AddComponent<T>();
}
}
}
return _instance;
}
}
}
该ObjObjHideOrShowManager继承了WeiHaiSingleTon,间接地实现了单例模式,该单例模式为其它类提供了ShowNWall、HideNWall、ShowNBorder、HideNBorder、ShowBWall、HideBBorder、HideBWall、ShowBBorder、HideAllWallsAndFlickBorder等9种服务,其他类可以通过ObjHideOrShowManager.Instance.服务名调用服务。
public class ObjHideOrShowManager : WeiHaiSingleTon<ObjHideOrShowManager>
{
private GameObject weihai_n_walls;
private GameObject weihai_n_FlickBorder;
private GameObject weihai_b_walls;
private GameObject weihai_b_FlickBorder;
private void Awake()
{
weihai_n_walls = GameObject.Find("weihai_n_walls");
weihai_n_FlickBorder = GameObject.Find("weihai_n_FlickBorder");
weihai_b_walls = GameObject.Find("weihai_b_walls");
weihai_b_FlickBorder = GameObject.Find("weihai_b_FlickBorder");
}
#region Hide area-edge or area-num
public void ShowNWall()
{
weihai_n_walls.SetActive(true);
}
public void HideNWall()
{
weihai_n_walls.SetActive(false);
}
public void ShowNBorder()
{
weihai_n_FlickBorder.SetActive(true);
}
public void HideNBorder()
{
weihai_n_FlickBorder.SetActive(false);
}
public void ShowBWall()
{
weihai_b_walls.SetActive(true);
}
public void HideBWall()
{
weihai_b_walls.SetActive(false);
}
public void ShowBBorder()
{
weihai_b_FlickBorder.SetActive(true);
}
public void HideBBorder()
{
weihai_b_FlickBorder.SetActive(false);
}
public void HideAllWallsAndFlickBorder()
{
weihai_b_FlickBorder.SetActive(false);
weihai_b_walls.SetActive(false);
weihai_n_walls.SetActive(false);
weihai_n_FlickBorder.SetActive(false);
}
#endregion
}