游戏相关设计模式的总结(一)

状态模式

“将多变的行为分离出来封装成状态,通过状态切换来改变呈现的行为。”

成员:

Context(状态拥有者,可以是任何有多种状态的类)、IState(状态接口)、State(状态类)

使用方法概述:

Context拥有IState状态接口对象m_State,指示当前状态。调用Context相关方法时调用m_State对应的方法呈现出不同行为,同时提供SetState方法修改当前状态。State要实现IState中会被Context调用的方法。状态切换的时机和条件可以由Context控制,但推荐的是让State拥有Context的引用,由State控制状态切换。

状态的切换有两种方式:

1、Context来控制,亲自维护各项判断条件

2、Context设置初始状态,之后由State负责(这样可以缩减Context的职责,而且State本身比较明白该切换到哪个State。不过这样需要把Context的引用传给State。)

示例:

public class Context{
    //当前状态
    IState m_State;
    
    //执行状态呈现的行为HandleX,即调用状态对象的相关函数(这里的'X'指的是可以有多种)
    public void RequestX(){};
    
    //切换状态
    public void SetState(IState state){
        m_State = state;
    }
}
​
public abstract class IState{
    //其拥有者,用于调用SetState切换状态
    Context m_Context;
    
    //初始化设置拥有者
    public void State(Context context){
        m_Context = context;
    }
    
    //用于呈现行为,由拥有者的RequestX调用
    public abstract void HandleX(){}
}

应用场景和优点:

单一职责:将State转换的职责分离出Context,Context只负责拥有和修改当前State

开闭:不用修改Context,增加新的State,即可扩展Context的呈现行为

依赖倒置:Context依赖IState接口,不必在意有哪些State具体类

1、降低维护难度,方便增加行为。代替了switch语句来切换状态,更优雅,减少可能的错误。一个状态相关的行为被封装在一个类中,清晰易维护。

2、外界对Context的使用方式不变,但呈现的行为却改变了。

3、状态类复用。例如游戏场景和其对应的场景状态类可以复用到不同项目中。(想想各个大厂的游戏登陆场景)

 

缺点:

虽然比传统的switch实现方式更易维护,但过多的状态类也麻烦。

 

应用:场景切换,角色AI,服务器连接状态

 

外观模式

“将多个接口封装在一个统一简单接口中,使内部接口之间的互动对外隐藏”

成员:

Facade(统一外观接口),SubSystemX(各个被统一的接口)

示例:

public class Facade
{
    //多个子系统
    private SubSystemX;
    
    //对外提供的接口
    public functionX(){
        //内部子系统协同,完成对外接口的功能
        SubSystem1.functionX();
        SubSystem2.functionX();
        SubSystem3.functionX();
        //......
    }
}

应用场景和优点:

迪米特:将原本对多个子系统SubSystem的操作封装成对一个接口Facade的操作,减少了互动对象

开闭:当子系统之间的合作完成的功能需要修改,只会影响统一接口Facade。

单一职责:子系统的合作由Facade负责。

1、节省时间,简洁。原本修改一个SubSystem需要修改引用它的多个类,现在只需修改Facade。

2、减少耦合,易于分工。

3、增加安全性。确保子系统按顺序协同工作。

 

缺点:

Facade有太多子系统会过于庞大而难以维护。

 

应用:UI组件

 

与其他模式结合:

使用单例的Facade。SubSystem之间的协同使用中介者模式,弥补互相之间沟通过于复杂的问题。

 

单例模式

“使类在全局只有一个对象,并通过一个全局的方法访问”

成员:

Singleton(单例类)

使用方法概述:

将构造方法设为private,对外提供获取类的静态单例instance的方法,在该方法中唯一地产生单例。

示例:

public class SingleTon{
    private static SingleTon instance;
    
    private static object _lock = new object();
    
    private SingleTon(){}
    
    public static SingleTone GetInstance(){
        if(instance == null){
            lock(_lock){
                if(instace == null){
                    return instance = new SingleTon();
                }
            }
        }
    }
}

应用场景和优点:

方便,省略创建对象,传参,对象和数据维持独一份,快速获取。

 

缺点:

违反开闭:单例对象是实现类而不是抽象类。

单例类无法被继承来实现多态,因为构造函数在内部调用,已经确定了实例化的对象。

 

 

应用:日志等工具,限制实例对象个数的类(网络连接)

 

中介者模式

“将多个对象之间的互相的引用改为多个对象对一个中介者的引用,由中介代替它们互动”

成员:

IMediator(中介者接口)、Mediator(中介者)、IColleague(同事接口)、Colleague(同事实现类)

使用方法概述:

Colleague拥有IMediator的对象,并通过Action调用Mediator的SendMessage发送消息。Mediator拥有多个Colleague,SendMessage执行时调用所有Colleague的Request处理消息。

示例:

public abstract class IColleague{
    //拥有Mediator的引用用于在方法中调用其SendMessage发送消息给其他Colleague
    protected IMediator m_Mediator;
    
    public Colleague(IMediadtor mediator){
        this.m_Mediator = mediator;
    }
    
    //用于被Mediator调用,传入消息,并执行相关操作
    public abstarct void Request(string Message);
}
​
public abstract class IMediator{
    //用于被Colleague调用传入消息,发送给所有Colleague消息,通过调用它们的Request
    public abstract void SendMessage(IColleague colleague, string message);
}

应用场景和优点:

迪米特:将多个Colleague之间的互相耦合改为对一个Mediator的耦合。

1、减少了多个对象之间的互相引用,方便维护。所有对象只用引用中介者这一个对象,它们的修改只会影响到中介者。

 

缺点:

Mediator维护的Colleague过多。

 

改进:

如果是多个对象与一个对象之间的互动的话,可以使用观察者模式。也就是说中介者模式适用于多个对象之间的互动。

 

应用:玩家界面和游戏系统之间的互动

 

参考:

《设计模式与游戏完美开发》

《HeadFirst设计模式》

https://www.cnblogs.com/dolphin0520/p/3919839.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值