设计模式专题
委托
定义和使用
关键字:delegate 将方法作为函数进行传递,简单地说,委托是一个类型,可以副职一个方法的的引用
//两种声明方式
delegate void MyDelegate1(int s)
delegate void MyDelegate2<T>(T x)
//声明委托
public delegate void ShowDelegate(); //无参
public delegate void ShowDelegate2(int a, int b); //有参
public delegate int ShowDelegate3(); //有返回值、无参
public delegate int ShowDelegate4(int a, int b); //有返回值、有参
public delegate void ShowDelegate5<T>(T x);
void Start()
{
//定义委托 注:定义的委托名不允许和函数名一致
ShowDelegate showDelegate = Show1;
ShowDelegate2 showDelegate2 = Show2;
ShowDelegate3 showDelegate3 = Show3;
ShowDelegate4 showDelegate4 = Show4;
ShowDelegate5<string> showDelegate5 = Show5;
//调用的两种方式
showDelegate();
showDelegate.Invoke();
showDelegate2(1, 2);
showDelegate2.Invoke(1, 2);
int a = showDelegate3();
int b = showDelegate3.Invoke();
Debug.Log(a);
Debug.Log(b);
int c = showDelegate4(2, 3);
int d = showDelegate4.Invoke(2, 3);
Debug.Log(c);
Debug.Log(d);
showDelegate5("五");
}
public void Show1()
{
Debug.Log("Show1");
}
public void Show2(int a, int b)
{
Debug.Log(a + b);
}
public int Show3()
{
return 1000;
}
public int Show4(int a , int b)
{
return a + b;
}
public void Show5(string a)
{
Debug.Log("Show5: " + a);
}
系统内置Action委托
不需要显示声明委托定义,Action委托可与函数名一致,不可有返回值
void Start()
{
Action action1 = Show1;
action1();
Action<int, int> action2 = Show2;
action2(1, 3);
//与普通委托的区别,Action委托可与函数名一致
Action action3 = action;
}
public void Show1()
{
Debug.Log("Show1");
}
public void Show2(int a,int b)
{
Debug.Log("Show2 = " + (a + b));
}
public void action()
{
}
系统内置Func委托
注意点:
- Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须要有返回值,不可void
- Func 表示没有输入参数,返回值为int类型的委托
- Func<object, string, int>表示传入参数为object, string,返回值为int类型的委托
- Func<T1, T2, T3, int> 表示传入参数为T1, T2, T3(泛型),返回值为int类型的委托
- 即返回最后一个参数类型的委托
void Start()
{
//Func可以不带传入参数,但必须要有返回值
Func<string> func1 = Show1;
string a = func1();
Debug.Log(a);
//带传入参数,最后一个参数为返回值类型
Func<string, int> func2 = Show2; //传入string参数,返回int类型
Debug.Log(func2("2"));
Func<int, string> func3 = Show3; //传入int参数,返回string类型
Debug.Log(func3(3));
}
string Show1()
{
return "Show1";
}
int Show2(string a)
{
return int.Parse(a);
}
string Show3(int a)
{
return a.ToString();
}
匿名方法
没有名字的方法
Action action = delegate()
{
Debug.log("匿名函数被执行");
}
action(); //执行匿名函数
event事件
其本身就是一种委托,只是该委托只能作为类的成员,且不可在类外进行调用
当作为A类的成员,event事件在外部类赋值时,只能通过+=的方法;而对于普通的Action,则可以=、+=、-=的方式进行赋值
event Action action;
void Start()
{
action = Show1;
action();
}
void Show1()
{
Debug.log("Show1 被执行");
}
多播委托
指在一个委托中注册多个方法,在注册方法时,可以在委托中使用***加号运算符***或者***减号运算符***来实现***添加***或***撤销***方法
Action action = Show1;
action += Show2;
action(); // 函数Show1和Show2都被执行
action -= Show2;
action(); //只执行函数Show1
action -= Show1;
action(); //报错,aciont为引用类型,引用类型的默认值是null,直接使用会报错空异常
if(action != null)
action() //不会报错,什么都不会输出
void Show1()
{
Debug.log("Show1 被执行");
}
void Show2()
{
Debug.log("Show2 被执行");
}
设计模式
单例模式
一个类只能有一个实例,也就是类只能在内部实例一次,然后提供这一实例,外部无法对此类实例化,主要用于各种管理器
特点
- 只能有一个实例
- 只能自己创建自己的唯一实例
- 全局唯一
设计思路
-
实例全局唯一:static静态变量属于全局,并不属于类对象本身
-
实例只能在类的内部发生:需要将构造函数私有化(private),需要提供一个供外部访问的变量
public class Mysingleton { //通过private static定义一个类的实例,这样这个实例就属于全局,符合单例的全局唯一 private static Mysingleton _instance = null; //通过public static提供一个供外部访问的变量,让这个变量获取类中的实例 public static Mysingleton Instance { get { if (_instance == null) //若 _instance = new Mysingleton(); return _instance; } } private Mysingleton() { Debug.Log("构造函数执行"); } public void Show() { Debug.Log("Show"); } } public class Singleton : MonoBehaviour { // Start is called before the first frame update void Start() { Mysingleton mysingle = Mysingleton.Instance; mysingle.Show(); } }
观察者模式
定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使他们能够自动更新自己。常被用来实现事件处理系统