(二)设计模式之游戏--依赖倒置原则

(二)设计模式之游戏–依赖倒置原则

引入问题:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决方案:将类A修改为依赖抽象I,类B和类C各自实现抽象I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率,实际上就是解耦合

在这里插入图片描述

在这里插入图片描述

(1)定义:

  1. 高层模块不应该依赖底层模块,他们都依赖于抽象(接口,抽象类等),抽象不应该依赖于细节,细节应该依赖于抽象。

  2. 要针对接口编程,不要针对实现编程。

(2)实现分析:

a) 代码要依赖于抽象的类,而不要依赖于具体的类,高层模块不依赖于底层的模块,要针对接口编程而不针对实现或者是具体类编程。

b) 实现依赖倒转原则常用的方式是在代码中使用抽象类或接口。

c) 依赖倒转原则要求客户端依赖于抽象耦合,以抽象的方式耦合是依赖倒转的关键

d) 依赖注入:

通过构造函数注入实例变量。

通过Setter方法注入实例变量。

通过 接口方法注入实例变量。

(3) 示例:

在游戏中经常会出现让玩家攻击各种怪物这个功能。

原始方案如下:

在这里插入图片描述

using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class Player : MonoBehaviour {

 

void Start () {

 

        Attack(new SoliderMonster());

    }

    void Attack(SoliderMonster soliderMonster)

    {

        soliderMonster.TakeAttack();

    }

}

 

public class SoliderMonster

{

    public void TakeAttack()

    {

        Debug.Log("SoliderMonster被攻击");

    }

 

}

看起来每什么问题,但当我们改为攻击其它类型的怪物时,我们就需要修改高层模块Attack方法,以适合我们的需求,这显然不符合我们的要求。根据引入问题的解决方案,我们可以一个怪物抽象类(Monster)然后,让各种怪物继承它,并实行该抽象,然后再让人物依赖该抽象。重构如下。
在这里插入图片描述

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

 

public class Player : MonoBehaviour {

 

 

    private Monster monster;

    void Start () {

        Setter(new MasterMonster());

        Attack();

        Setter(new SoliderMonster());

        Attack();

    }

 

    public void Setter(Monster target)

    {

        monster = target;

    }

    void Attack()

    {

        monster.TakeAttack();

    }

}

public abstract class Monster

{

    public abstract void TakeAttack();

}

 

public class SoliderMonster: Monster

{

    public override void TakeAttack()

    {

        Debug.Log("SoliderMonster被攻击");

    }

 

}

 

public  class MasterMonster: Monster

{

    public override void TakeAttack()

    {

        Debug.Log("MasterMonster被攻击");

    }

}

在这里插入图片描述
现在当新增怪物时,我们只需让我们新增的具体怪物类继承自抽象怪物类即可,玩家类基本上不用改变。

其它依赖注入方式:

上面我们使用的是通过Setter方法注入实例变量。当然还有构造器注入、接口方法注入。

接口方法注入实例变量:

 void Attack(Monster monster)
    {
        monster.TakeAttack();
    }

通过构造函数注入实例变量,值得注意的是Unity继承自MonoBehaviour的类不能使用new 关键字通过构造方法来构造。

 public Player(Monster target)
    {
        monster = target;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值