• 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. 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
  • 相关阅读:
    项目实施(一)
    比较2个DataTable中的内容是否相同的方法
    [三、页面布局]18使用ScrollView在限定的区域显示超长的内容
    [三、页面布局]14使列表同时支持删除和移动记录的功能
    [三、页面布局]15使用Section将列表氛围几个组
    [三、页面布局]13调整记录在List列表里的顺序
    [三、页面布局]22制作一份漂亮而强大的表单
    [三、页面布局]16使用tintColor单独设置列表中的图表颜色
    [三、页面布局]20创建两层嵌套的滚动视图
    [三、页面布局]19创建一个水平方向上的滚动视图
  • 原文地址:https://www.cnblogs.com/Fflyqaq/p/11665541.html
Copyright © 2020-2023  润新知