设计模式04———桥接模式 c#

news2024/11/23 11:40:30

桥接模式:将一个事物从多个维度抽象出来,采用 分离 和 组合 的方式 替代 原本类的继承

桥接模式(Bridge Pattern)是一种软件设计模式,属于结构型模式,它用于将抽象部分与具体实现部分分离,以便它们可以独立地变化。这种模式通过创建一个连接(桥)来将抽象和实现部分分离,从而允许它们可以独立地进行扩展和变化。

桥接模式的主要目标是解耦抽象部分(如类或对象)和实现部分(如具体类或对象),从而可以分别对它们进行扩展或修改,而不会相互影响。这提供了更大的灵活性和可维护性,特别是在需要支持多种不同的抽象和实现组合的情况下。

通常,桥接模式包括以下角色:

  1. 抽象(Abstraction):定义抽象部分的接口,并维护一个指向实现部分的引用。通常包含抽象方法,用于委托实现部分完成具体工作。

  2. 具体抽象(Concrete Abstraction):实现抽象接口,通常是一个具体类,它与实现部分关联,将抽象方法的调用委托给实现部分。

  3. 实现(Implementor):定义实现部分的接口,通常包含实现方法,这些方法可以被具体实现类重写以提供不同的实现。

  4. 具体实现(Concrete Implementor):实现实现接口,提供具体的实现逻辑。

桥接模式的典型应用包括在图形系统中将不同的形状(抽象部分)和不同的颜色(实现部分)组合起来,以实现各种不同的图形。通过使用桥接模式,可以轻松地添加新的形状或颜色,而不需要修改已有的代码,实现了系统的可扩展性和可维护性。这是一个典型的例子,但桥接模式在各种其他领域也有广泛的应用。

namespace BridgePatternFour{
    //魔法效果抽象类
    public abstract class IMagic{
        //施放魔法
        public abstract void Cast();
    }
}

using System;
namespace BridgePatternFour{
    public class MagicFire : IMagic{
        public override void Cast(){
            Console.WriteLine("同时释放火焰魔法");
        }
    }
}

using System;
namespace BridgePatternFour{
    public class MagicSnow : IMagic{
        public override void Cast(){
            Console.WriteLine("同时释放冰冻魔法");
        }
    }
}
 

抽象武器基类

武器子类

using System;
namespace BridgePatternFour{
    public class WeaponSword : IWeapon{
        public WeaponSword(string name, IMagic magic) : base(name, magic){
        }
        public override void Attack(){
            //待改进写死的实现  
            Console.WriteLine($"挥舞{Name}发动攻击");
            //抽象部分
            _magic.Cast();
        }
    }
}
动作基类

namespace BridgePatternFour{
    public abstract class IAction{
        //动作名称
        public string Name { set; get; }
        //播放动作动画
        public abstract void Behaviour();
        public IAction(string name) {
            Name = name;
        }
    }
}
动作子类

using System;
namespace BridgePatternFour{
    public class ActionStab : IAction{
        public ActionStab(string name) : base(name){
        }
        public override void Behaviour(){
            Console.WriteLine($"播放{Name}刺动作");
        }
    }
}

using System;
namespace BridgePatternFour{
    public class ActionCut : IAction{
        public ActionCut(string name) : base(name){
        }
        public override void Behaviour(){
            Console.WriteLine($"播放{Name}砍动作");
        }
    }
}

更新武器基类

namespace BridgePatternFour{
    public abstract class IWeapon{
        //武器名称
        public string Name { get; set; }
        //魔法的引用
        protected IMagic _magic = null;
        //动作的引用
        protected IAction _action = null;
        //构造方法
        public IWeapon(string name, IMagic magic) {
            Name = name;
            _magic = magic;
        }
        //抽象攻击方法
        public abstract void Attack();
        //设置动作
        //注意:此方法不许重写,延申到子类没有意义
        public void SetAction(IAction action) {
            _action = action;
        }  
    }
}

更新武器子类

using System;
namespace BridgePatternFour{
    public class WeaponSword : IWeapon{
        public WeaponSword(string name, IMagic magic) : base(name, magic){
        }
        public override void Attack(){
            Console.WriteLine($"{Name}发动攻击");
            //抽象部分
            if(_action != null)
                _action.Behaviour();
            //抽象部分
            if(_magic != null)
                _magic.Cast();
        }
    }
}
修改动作基类 接近接口

namespace BridgePatternFour{
    public abstract class IAction{
        //动作名称
        protected string Name { set; get; }
        //播放动作动画
        public abstract void Behaviour();
    }
}
修改动作子类

using System;
namespace BridgePatternFour{
    public class ActionStab : IAction{
        public override void Behaviour(){
            Console.WriteLine($"播放{Name}刺动作");
        }
    }
}

using System;
namespace BridgePatternFour{
    public class ActionStab : IAction{
        public override void Behaviour(){
            Console.WriteLine($"播放{Name}刺动作");
        }
        public ActionStab() {
            Name = "刺";
        }
    }
}
同样

using System;
namespace BridgePatternFour{
    public class ActionCut : IAction{
        public override void Behaviour(){
            Console.WriteLine($"播放{Name}砍动作");
        }
        public ActionCut() {
            Name = "砍";
        }
    }
}
更新Program类

namespace BridgePatternFour{
    public class Program{
        public static void Main(string[] args) {
            IWeapon weapon = new WeaponSword("倚天剑", new MagicSnow());
            weapon.SetAction(new ActionStab());
            weapon.Attack();
        }
    }
}
此时是单维度的(单剑),加一个弓变成双维度(双剑弓)

using System;
namespace BridgePatternFour{
    public class WeaponBow : IWeapon{
        public WeaponBow(string name, IMagic magic) : base(name, magic){
        }
        public override void Attack(){
            Console.WriteLine($"{Name}发动攻击");
            //抽象部分
            if (_action != null)
                _action.Behaviour();
            //抽象部分
            if (_magic != null)
                _magic.Cast();
        }
    }
}
此时会发现增加一个新类除了武器类名不一样其他都是一样的,导致这个原因是该项目不需要,如果在需要一些热武器就可以去除其原有的抽象实现部分,因项目而异


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1153372.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud(三) Ribbon负载均衡

SpringCloud(二) Eureka注册中心的使用-CSDN博客 在SpringCloud(二)中学习了如何通过Eureka实现服务的注册和发送,从而通过RestTemplate实现不同微服务之间的调用,加上LoadBalance注解之后实现负载均衡,那负载均衡的原理是什么呢? 目录 一, 负载均衡 1.1 负载均衡原理 1.2 源…

怎么用python代码查看可用的gpu,然后指定可用的gpu运行

查看gpu import torch# 检查CUDA是否可用 if torch.cuda.is_available():# 获取GPU设备数量device_count torch.cuda.device_count()# 列出可用的GPU设备for i in range(device_count):print(f"GPU {i}: {torch.cuda.get_device_name(i)}") else:print("CUDA …

JZ22链表中倒数最后k个节点

JZ22链表中倒数最后k个节点 解法一 双指针法,定义两个快慢指针,先让快指针走k步,然后让两个指针以相同速度向前,直到快指针走到尾部none的位置,此时慢指针正好在倒数第k的位置此方法的时间复杂度为O(n&…

Ubuntu Desktop 20.04升级gcc-11

默认自带的gcc是9,需要升级到11 sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt update sudo apt install gcc-11 sudo apt install g11 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 50 sudo update-alternatives -…

数字孪生三剑客!云渲染及虚拟仿真服务器产品MapGIS Server for Unreal来了

10月18日,新一代全空间智能GIS平台的升级之作——MapGIS 10.6 Pro在深圳正式发布,整场发布会全空间GIS、智能GIS、信创GIS、全栈开发各维度创新一一揭晓,全空间一体化、深度融合云端的全系产品全面升级,科技盛宴、高潮迭起。其中尤…

海外跨境电商云厂商阿里云、华为云、九河云选择攻略

近几年出海已成为趋势,而要打有准备的仗,就必须先收集关键信息。国内企业出海需要对海外市场进行深入的分析和挖掘,数据分析技术可以帮助国内企业更好地了解海外市场的需求和趋势,包括市场调研、用户画像、销售数据分析等方面&…

UnrealSynth虚幻合成数据生成器

UnrealSynth 虚幻合成数据生成器利用虚幻引擎的实时渲染能力搭建逼真的三维场景,为 YOLO 等 AI 模型的训练提供自动生成的图像和标注数据。UnrealSynth 生成的合成数据可用于深度学习模型的训练和验证,可以极大地提高各种行业细分场景中目标识别任务的实…

RCD负载箱的价格和性价比如何?

RCD负载箱用于测试电力设备的专用设备,主要用于检测电路的电流、电压和功率等参数。 RCD负载箱的价格与其品牌、型号、功能和性能有关,知名品牌和高性能的RCD负载箱价格会相对较高,而一些普通品牌或功能较简单的RCD负载箱价格则相对较低&…

使用 :has() 选择前一个相邻元素

使用 CSS :has() 选择前一个兄弟姐妹 CSS 更令人抓狂的限制之一是长期以来它无法根据其子元素或前一个兄弟元素来选择元素。这使得构建可以针对元素的先前同级元素的 CSS 选择器变得不可能,但是has:()伪类(以及来自选择器级别 4 的、 和)已经…

【C++入门 二 】学习使用C++命名空间及其展开

C入门 二 1. C第一个小程序2.命名空间2.1命名冲突2.2 命名空间2.2.1 命名空间定义2.2.2.命名空间的展开方式1(直接展开)方式2(指定展开) 3.C输入&输出①输出②输入 1. C第一个小程序 下面这段代码有两个特性 1、io流 2、命名空…

innovus:如何解决editAddRoute不能在平行线间打孔的问题

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 用户使用editAddRoute命令或者图形界面手动拉线,默认只能在相同net 的不同层net shape crossover(交叉)位置上打孔,如图右侧GNDD交叉的位置有打孔,而左侧平行的两条net shape无法自动打孔。 有…

众和策略:鸿蒙4升级设备数量破亿;财政部调整保险公司考核方式

重要的消息有哪些 财政部调整保险公司查核办法 增强险资入市积极性 财政部10月30日消息显现,近日已印发《关于引导保险资金长时间稳健投资、调整国有商业保险公司绩效评价相关指标的告诉》(下称《告诉》),清晰将国有商业保险公司…

​CRM中的大客户销售是什么?​

对企业来说,大客户可能贡献了大部分的销售业绩。什么样的客户可以被认定为是大客户?大客户销售与普通销售有何区别?针对大客户又该采取什么样的销售策略呢?从回答这几个问题开始,我们来说说CRM中的大客户销售是什么&am…

数智领航未来∣2023契约锁企企通专题沙龙:数字建设,为企业高质量发展注入新动能

今年两会期间,“数字经济”是当之无愧的热词之一。中央经济工作会议提出,要大力发展数字经济,提升常态化监管水平,支持平台经济发展。 当前数据作为新型生产要素,价值尚未得到充分释放,需要疏通数据要素流通…

Microsoft 365 管理自动化

Microsoft 365 服务被大多数组织广泛使用,每天生成的数据量巨大。解决 Microsoft 365 中的问题可能非常困难,并且使用多个管理中心来保护组织变得复杂。本机控制台还缺少某些批量管理任务、全面的审计报告和基于角色的精细访问控制。 Microsoft 360 管理…

2、NLP文本预处理技术:词干提取和词形还原

一、说明 在上一篇文章中,我们解释了文本预处理的重要性,并解释了一些文本预处理技术。在本文中,我们将介绍词干提取和词形还原主题。 词干提取和词形还原是两种文本预处理技术,用于将单词还原为其基本形式或词根形式。这些技术的…

OpenGL ES相关库加载3D 车辆模型

需求类似奇瑞的这个效果,就是能全方位旋转拖拽看车,以及点击开关车门车窗后备箱等 瑞虎9全景看车 (chery.cn) 最开始收到这个需求的时候还有点无所适从,因为以前没有做过类似的效果,后面一经搜索后发现实现的方式五花八门&#xf…

十月听书笔记

十月听书笔记 1、《宝贵的人生建议》2、《后工作时代》3、《我们何以不同》4、《恰到好处的帮助》5、《24个比利》6、《恰到好处的安慰》7、《为什么越无知的人越自信》8、《陌生人效应》9、《往里走,安顿自己》10、《为什么学生不喜欢上学》11、《自律力》12、《弹…

浅析Redis大Key | 京东云技术团队

一、背景 在京东到家购物车系统中,用户基于门店能够对商品进行加车操作。用户与门店商品使用Redis的Hash类型存储,如下代码块所示。不知细心的你有没有发现,如果单门店加车商品过多,或者门店过多时,此Key就会越来越大…

Qt之基于QCustomPlot绘制直方图(Histogram),叠加正态分布曲线

一.效果 二.原理 1.正态分布 高斯分布(Gaussian distribution),又名正态分布(Normal distribution),也称"常态分布",也就是说,在正常的状态下,一般的事物,都会符合这样的分布规律。 比如人的身高为一个随机变量,特别高的人比较少,特别矮的也很少,大部分都…