Unity---游戏设计模式(5)之桥接模式




概述参考请看 参考博客

现在假如我们需要使用2种引擎分别绘制三种图形。
当不使用桥接模式时:

使用桥接模式

这样不仅减少了类的数量,也降低了引擎和图形类之间的耦合度。

1、桥接模式

桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式。

桥接模式原型UML图

桥接模式原型代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 桥接模式
/// </summary>
public class BridgeMode : MonoBehaviour
{
    private void Start()
    {
        IEngine openGL = new OpenGL();
        IEngine directX = new DirectX();

        IShape cube = new Cube(openGL);
        IShape sphere = new Sphere(directX);
        IShape capsule = new Capsule(openGL);

        cube.Draw();
        sphere.Draw();
        capsule.Draw();

    }
}

/// <summary>
/// 图形类
/// </summary>
public abstract class IShape
{
    protected string mShapeName;
    protected IEngine mEngine;

    public IShape(IEngine engine)
    {
        mEngine = engine;
    }

    public void Draw()
    {
        mEngine.DrawShape(mShapeName);
    }
}

public class Cube : IShape
{
    public Cube(IEngine engine)
        : base(engine)
    {
        mShapeName = "Cube";
    }

}
public class Sphere : IShape
{
    public Sphere(IEngine engine)
        : base(engine)
    {
        mShapeName = "Sphere";
    }

}
public class Capsule : IShape
{
    public Capsule(IEngine engine)
        : base(engine)
    {
        mShapeName = "Capsule";
    }

}

/// <summary>
/// 引擎类
/// </summary>
public abstract class IEngine
{
    public abstract void DrawShape(string shapeName);
}

public class OpenGL : IEngine
{
    public override void DrawShape(string shapeName)
    {
        Debug.Log("OpenGL绘制图形:" + shapeName);
    }
}
public class DirectX : IEngine
{
    public override void DrawShape(string shapeName)
    {
        Debug.Log("DirectX绘制图形:" + shapeName);

    }
}

2、桥接模式: 用于角色手持武器

不同的角色可以手持不同的武器射击

桥接模式实例UML图

桥接模式实例代码

/// <summary>
/// 桥接模式
/// </summary>
public class Client : MonoBehaviour
{
    private void Start()
    {
		//角色可以手持不同的枪,但一把枪只能被一个人手持
        ICharacter characterRookie = new SoldierRookie();
        ICharacter characterCaptain = new SoldierCaptain();
        IWeapon weaponGun = new WeaponGun(characterRookie);
        IWeapon weaponRocket = new WeaponRocket(characterCaptain);

        //武器枪攻击
        characterRookie.Weapon = weaponGun;
        characterRookie.Shoot(Vector3.one);

        characterRookie.Weapon = weaponRocket;
        characterRookie.Shoot(Vector3.one);
    }
}

/// <summary>
/// 角色
/// </summary>
public abstract class ICharacter
{
    /// <summary>
    /// 角色名字
    /// </summary>
    protected string mCharacterName;
    public string CharacterName { get { return mCharacterName; } }
    /// <summary>
    /// 角色手中的武器
    /// </summary>
    protected IWeapon mWeapon;
    public IWeapon Weapon { set { mWeapon = value; } }

    /// <summary>
    /// 射击
    /// </summary>
    public abstract void Shoot(Vector3 targetPosition);
}
public class SoldierRookie : ICharacter
{
    public SoldierRookie()
    {
        mCharacterName = "Rookie";
    }

    public override void Shoot(Vector3 targetPosition)
    {
        if (mWeapon != null)
        {
            mWeapon.Fire(targetPosition);
        }
    }
}
public class SoldierCaptain : ICharacter
{
    public SoldierCaptain()
    {
        mCharacterName = "Captain";
    }

    public override void Shoot(Vector3 targetPosition)
    {
        if (mWeapon != null)
        {
            mWeapon.Fire(targetPosition);
        }
    }
}

/// <summary>
/// 角色手中的武器
/// </summary>
public abstract class IWeapon
{
    /// <summary>
    /// 拿着武器的角色
    /// </summary>
    protected ICharacter mCharacter;

    public IWeapon(ICharacter character)
    {
        mCharacter = character;
    }

    /// <summary>
    /// 武器开火
    /// </summary>
    public abstract void Fire(Vector3 targetPosition);
}
public class WeaponGun : IWeapon
{
    public WeaponGun(ICharacter character)
        : base(character)
    {
    }

    public override void Fire(Vector3 targetPosition)
    {
        Debug.Log("人物" + mCharacter.CharacterName + "使用Gun攻击位置:" + targetPosition);
    }
}
public class WeaponRocket : IWeapon
{
    public WeaponRocket(ICharacter character)
        : base(character)
    {
    }

    public override void Fire(Vector3 targetPosition)
    {
        Debug.Log("人物" + mCharacter.CharacterName + "使用Rocket攻击位置:" + targetPosition);
    }
}

3、桥接模式优缺点

优点

  1. 分离抽象接口及其实现部分。
  2. 桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法。
  3. 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
  4. 实现细节对客户透明,可以对用户隐藏实现细节。

缺点

  1. 增加了理解和设计难度。
  2. 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
原文地址:https://www.cnblogs.com/Fflyqaq/p/11665541.html