概述参考请看 参考博客
现在假如我们需要使用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、桥接模式优缺点
优点
- 分离抽象接口及其实现部分。
- 桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法。
- 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
- 实现细节对客户透明,可以对用户隐藏实现细节。
缺点
- 增加了理解和设计难度。
- 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。