单例
保证一个类仅有一个实例,并提供一个访问它的全局访问点
保证在一个项目中的不同模块中获取对象,获取到的是同一个对象
实现 & 步骤
- 定义一个类
class User { }
- 私有化构造方法 - 防止用户通过 new 的方式多次实例化对象(多次实例化对象不能得到同一个对象)
class User {
private User() { }
}
- 提供一个private权限的静态的当前类的对象(此对象只会在第一次实例化后只执行一次,故而多次实例化还是这个对象)
class User {
private User() { }
private static User instance = new User();
}
- 目前无法实例化对象,因为没有暴露权限的方法(需要提供一个public权限的静态方法用于返回当前类的对象)
class User {
private User() { }
private static User instance = new User();
public static User CurrentUser(){
return instance;
}
}
- 调用
User lee = User.CurrentUser();
User zhang = User.CurrentUser();
Console.WriteLine(lee == zhang); // True lee和zhang是同一个对象
- 完整代码
class MainClass
{
public static void Main(string[] args)
{
User lee = User.CurrentUser();
User zhang = User.CurrentUser();
Console.WriteLine(lee == zhang); // True lee和zhang是同一个对象
}
}
class User {
private User() { }
private static User instance = new User();
public static User CurrentUser(){
return instance;
}
}
以上方法解释
- 定义了一个类用于提供对象
class User {}
- 以下这种实例化方法会让
lee
和zhang
各拥有一个独立的对象
User lee = new User();
User zhang = new User();
Console.WriteLine(lee == zhang); // False
- 而现在提出一个需求需要要求
lee
和zhang
共享一个对象,那么就不能让用户能多次去实例化,私有化构造方法能解决此问题
// User lee = new User(); // Error 因为实例化的函数是私有的
// User zhang = new User(); // Error 因为实例化的函数是私有的
class User {
private User() { }
}
- 由于不能实例化对象了,这时
lee
和zhang
不会拥有对象了,但是lee
和zhang
还是想拥有对象,所以这时候需要创建一个静态的方法去为lee
和zhang
提供对象
User lee = User.CurrentUser();
User zhang = User.CurrentUser();
Console.WriteLine(lee == zhang); // False
class User {
private User() { }
public static User CurrentUser() {
return new User();
}
}
- 但是这种方法还是每次实例化都会重新创建一个对象,不会让
lee
和zhang
共享一个对象 - 那么这个时候就需要在类中定义一个多次实例也只会执行一次属性, 然后让定义的
CurrentUser
方法返回这个多次实例也只会执行一次属性
User lee = User.CurrentUser();
User zhang = User.CurrentUser();
Console.WriteLine(lee == zhang); // True
class User {
private User() { }
public static User CurrentUser() {
return instance;
}
private static User instance = new User();
}
- 所以他们共享了一个对象
变式
User lee = User.CurrentUser();
User zhang = User.CurrentUser();
Console.WriteLine(lee == zhang); // True
class User {
private User() { }
public static User CurrentUser() {
if(instance == null) instance = new User();
return instance;
}
private static User instance;
}
User lee = User.instance;
User zhang = User.instance;
Console.WriteLine(lee == zhang); // True lee和zhang是同一个对象
class User {
private User() { }
public static readonly User instance = new User();
}
示例
实现一个英雄类,实现购买英雄,当英雄购买超过10个后不允许购买
class MainClass
{
public static void Main(string[] args)
{
HeroManager heroManager = HeroManager.heroManager;
Hero hero = new Hero
{
name = "xxx",
price = 100d,
hp = 1000,
mp = 1000
};
bool result = heroManager.BuyHero(hero);
if (result)
{
Console.WriteLine("buy success");
}
else
{
Console.WriteLine("buy fail");
}
}
}
struct Hero {
public string name;
public double price;
public int hp;
public int mp;
}
class HeroManager
{
private HeroManager() { } // 单例模式
public static readonly HeroManager heroManager = new HeroManager(); // 单例模式
// 存储购买的英雄
public Hero[] allHeros = new Hero[10];
// 记录英雄购买个数
private int count = 0;
// 购买英雄
public bool BuyHero(Hero hero) {
if (count >= 10) return false;
// 将英雄添加到存储
allHeros[count++] = hero;
return true;
}
}