Unity实现设计模式——适配器模式

Unity实现设计模式——适配器模式

适配器模式又称为变压器模式、包装模式(Wrapper) 将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
在一个在役的项目期望在原有接口的基础上拓展,那么适配器模式是最适合的。 即需要使用一个已有或新建的类,但这个类又不符合系统的接口,则可以使用适配器模式。

client:需要使用适配器的对象,不需要关心适配器内部的实现,只对接目标角色。
Target:目标角色,和client直接对接,定义了client需要用到的功能。
Adaptee:需要被进行适配的对象。
Adapter:适配器,负责将源对象转化,给client做适配。

在这里插入图片描述
下面还是使用两个例子来说明适配器模式

(一)使用比较抽象的例子来说明

1.Target

class Target
{
    public virtual void Request()
    {
        Debug.Log("Called Target Request()");
    }
}

2.Adaptee

class Adaptee
{
    public void SpecificRequest()
    {
        Debug.Log("Called SpecificRequest()");
    }
}

可以看到目标对象和待适配对象并不匹配
使用适配器来让二者联系起来

3.Adapter

class Adapter : Target
{
    private Adaptee _adaptee = new Adaptee();

    public override void Request()
    {
        // Possibly do some other work
        //  and then call SpecificRequest
        _adaptee.SpecificRequest();
    }
}

4.测试

public class AdapterStructure : MonoBehaviour
{
	void Start( )
    {
        // Create adapter and place a request
        Target target = new Adapter();
        target.Request();
    }
}

可以发现两个无关的类很自然的就联系起来了!

(二)使用具体的例子来说明

现在有敌方攻击者的基类,派生出了敌方坦克,同时有敌方机器人但是机器人的接口和敌方攻击者的接口不同,我们需要进行适配

1. IEnemyAttacker

    public interface IEnemyAttacker
    {
        void FireWeapon();
        void DriveForward();
        void AssignDriver(string driver);
    }

2. EnemyTank

    public class EnemyTank : IEnemyAttacker
    {
        public void FireWeapon()
        {
            int attackDamage = Random.Range(1, 10);
            Debug.Log("Enemy Tank does " + attackDamage + " damage");
        }

        public void DriveForward()
        {
            int movement = Random.Range(1, 5);
            Debug.Log("Enemy Tank moves " + movement + " spaces");
        }

        public void AssignDriver(string driver)
        {
            Debug.Log(driver + " is driving the tank");
        }
    }

3. EnemyRobot

    public class EnemyRobot
    {
        public void SmashWithHands()
        {
            int attackDamage = Random.Range(1, 10);
            Debug.Log("Robot causes " + attackDamage + " damage with it hands");
        }

        public void WalkForward()
        {
            int movement = Random.Range(1, 3);
            Debug.Log("Robot walks " + movement + " spaces");
        }

        public void ReactToHuman(string driverName)
        {
            Debug.Log("Robot tramps on " + driverName);
        }
    }

可以看出这里不同,当然可以对EnemyRobot派生自IEnemyAttacker接口,然后重新实现接口,但是在多人协作的场景,这样是不允许的。同时该类可能在别处引用,显然有很大的工作量要修改。

4. EnemyRobotAdaper

    public class EnemyRobotAdaper : IEnemyAttacker
    {
        EnemyRobot robot;

        public EnemyRobotAdaper(EnemyRobot robot)
        {
            this.robot = robot;
        }

        public void FireWeapon()
        {
            robot.SmashWithHands();
        }

        public void DriveForward()
        {
            robot.WalkForward();
        }

        public void AssignDriver(string driver)
        {
            robot.ReactToHuman(driver);
        }
    }

5.测试

    public class AdapterPatternExample2 : MonoBehaviour
    {
        void Start()
        {
            IEnemyAttacker tank = new EnemyTank();

            EnemyRobot fredTheRobot = new EnemyRobot();
            IEnemyAttacker adapter = new EnemyRobotAdaper(fredTheRobot);

            fredTheRobot.ReactToHuman("Hans");
            fredTheRobot.WalkForward();

            tank.AssignDriver("Frank");
            tank.DriveForward();
            tank.FireWeapon();

            adapter.AssignDriver("Mark");
            adapter.DriveForward();
            adapter.FireWeapon();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值