Jenner's Blog

不变秃,也要变强!

0%

其他几种常用的设计模式

工厂模式

简单工厂

一个公有接口,不同类有不同的实现方式。工厂中通过条件分支实例化不同的产品。

工厂方法

有四个角色,抽象工厂,具体工厂,抽象产品,具体产品。不再是由一个工厂类去实例化具体的产品,而是由抽象工厂的子类具体工厂去实例化产品。
具体工厂生产具体产品,解除了工厂与条件分支的耦合。

抽象工厂

与工厂方法模式不同的是,工厂方法模式中的工厂只生产单一的产品,而抽象工厂模式中的工厂生产多个产品。

Unity中的使用

对象池使用抽象工厂模式:对象池抽象基类定义接口,两个子类分别完成GameObject和ab包的管理。

适配器模式

随着项目需求的变动,需要接入新的功能类,但是新类的接口与原有的接口定义不一致,就需要用到适配器模式。分别有类适配器和对象适配器(优先选择)。

装饰器模式

对已有的业务逻辑进一步的封装,使其增加额外的功能。继承父类,并增加功能函数。

举例

使用C#中的this扩展方法。比如lua框架封装按钮的监听点击事件,回调lua 方法。

命令模式

有两个角色:

  1. 调用者Invoker,一般为控制器或角色,得到客户端输入,调用具体的命令;
  2. 接受者Receiver,一般为角色,提供命令的具体执行方法。

命令模式主要的特点是把调用者和接受者之间的连接——命令——类化,把命令(Command)独立出来一个,成为一个单独的层用来连接调用者和接受者。然后调用者(Invoker)调用命令,命令通知接受者(Receiver)具体的执行逻辑。

违反开闭原则的写法:

1
if(Input.GetKey(KeyCode.W)){//向前移动的具体逻辑}

这里调用和执行高度耦合,如果要修改向前移动的逻辑,或者更换向前移动的按键,需要直接修改上面的代码。

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public interface ICommand {
void Execute(Receiver receiver);
}


public class MoveForwardCommand : ICommand {
public void Execute(Receiver receiver){
receiver.MoveForward();
}
}

public class MoveBackCommand : ICommand {
public void Execute(Receiver receiver){
receiver.MoveBack();
}
}

// 具体的移动方法
public class Receiver : MonoBehaviour {
public float speed = 6f;
CharacterController characterController;
Vector3 moveDir = Vector3.zero;
void Awake(){
characterController = GetComponent<CharacterController>();
}

public void MoveForward(){
moveDir = transform.TransformDirection(Vector3.forward) * speed;
characterController.Move(moveDir * Time.deltaTime);
}

public void MoveBack(){
moveDir = transform.TransformDirection(Vector3.back) * speed;
characterController.Move(moveDir * Time.deltaTime);
}
}

迭代器模式

C#自带的迭代器。

1
2
3
4
5
6
7
8
9
10
11
12
13
//  枚举器接口 IEnumerator
public interface IEnumerator
{
object Current { get; }
// 如果是返回 false,就是结束迭代器块
bool MoveNext();
void Reset();
}
// 可枚举的接口 IEnumerable, 返回枚举器接口
public interface IEnumerable
{
IEnumerator GetEnumerator();
}

点击下方打赏按钮,获得支付宝二维码