适配模式桥接模式代理模式区别(设计模式七)
适配模式桥接模式代理模式区别(设计模式七)
2024-09-27 05:45:20  作者:遗我双鲤鱼  网址:https://m.xinb2b.cn/tech/vnw174188.html

大家好,欢迎来到编程队伍,我是作者王小伍,你可以叫我伍先生

这篇文章是设计模式系列文章的第七篇:桥接模式

设计模式系列前几篇没看的可以点击对应的文章快速查看

设计模式(一):单例模式

设计模式(二):工厂模式

设计模式(三):生成器模式

设计模式(四):原型模式

设计模式(五):适配器模式

设计模式(六):装饰器模式

正文

我们还是老规矩,用一个具体案例开始我们的设计模式之旅

一般去景区游玩,买门票时针对儿童、老人、军人、医护人员或其他特定人群会有一定的优惠:比如儿童6折,老人5折

假如有A、B两个景区,A景区门票原价100,B景区门票原价150。那么,这两个景区的儿童票和老人票如下

A景区儿童票 A景区老人票 B景区儿童票 B景区老人票 100 * 0.6 = 60 100 * 0.5 = 50 150 * 0.6 = 90 150 * 0.5 = 75

我们用代码来实现一下,代码结构应该是这样的


代码写完了,但是还不够完美。我们需要考虑代码的扩展性

假如后续有针对军人、医护人员的优惠该怎么扩展?你可能会说再增加对应的类不就行了

确实可以,但是如果是又增加了C景区、D景区呢,这时候增加的就不只是一两个类了


需要增加的类是几何倍的增长,最终我们的类会变得非常多。而且每次新增时不只是一个类,而是N个类

比如,新增景区时,有几种优惠人群就需要新增几个类。反之也一样,需要新增优惠人群时,有几个景区就需要新增几个类

要解决这个问题,就需要使用到桥接模式

我们可以把代码进行抽象,使景区和优惠政策相互独立不耦合,就像是这样


如图右上角,新建一个 People 接口类,儿童类和老人类都实现这个接口,可以在 getSale() 方法中返回对应的折扣

A 和 B 两个景区类,各自把 People类作为成员变量引入进来,此时 people就是一个桥梁。A 景区和 B 景区可以调用 people.getSale()来计算对应人群的门票价格

这样改完以后,无论是新增景区还是新增优惠人群,都只需要新增一个类即可

用 java 代码来实现一下:

People接口类

public interface People { String getSale();}

儿童类

public class Children implements People { @Override public String getSale() { return "0.6"; //儿童票6折 }}

老人类

public class OlderPeople implements People { @Override public String getSale() { return "0.5"; // 老人票5折 }}

门票接口类

public interface Tickets { int getMoney();}

A景区门票类

public class ATickets implements Tickets{ private People people; public ATickets(People people) { this.people = people; } @Override public int getMoney() { String sale = people.getSale(); // 获得折扣 BigDecimal saleBigDecimal = new BigDecimal(sale); // java小数计算会丢失精度,要用BigDecimal来计算 BigDecimal ticketsBigDecimal = new BigDecimal("100"); // a景区门票原价100 return ticketsBigDecimal.multiply(saleBigDecimal).intValue(); // 原价门票乘以折扣 }}

B景区门票类

public class BTickets implements Tickets{ private People people; public BTickets(People people) { this.people = people; } @Override public int getMoney() { String sale = people.getSale(); // 获得折扣 BigDecimal saleBigDecimal = new BigDecimal(sale); // java小数计算会丢失精度,要用BigDecimal来计算 BigDecimal ticketsBigDecimal = new BigDecimal("150"); // b景区门票原价100 return ticketsBigDecimal.multiply(saleBigDecimal).intValue(); // 原价门票乘以折扣 }}

模拟调用

public static void main(String[] args) { People children = new Children(); People olderPeople = new OlderPeople(); Tickets aTickets = new ATickets(children); System.out.println("A景区儿童票=" aTickets.getMoney()); aTickets = new ATickets(olderPeople); System.out.println("A景区老人票=" aTickets.getMoney()); Tickets bTikcets = new BTickets(children); System.out.println("B景区儿童票=" bTikcets.getMoney()); bTikcets = new BTickets(olderPeople); System.out.println("B景区老人票=" bTikcets.getMoney()); }

模拟调用最后输出结果如下

A景区儿童票=60

A景区老人票=50

B景区儿童票=90

B景区老人票=75

基本介绍

桥接模式是比较常用的设计模式之一,在创建型模式、结构型模式和行为型模式分类中,桥接模式归属于结构型模式

桥接模式可以将一个大类或者一系列紧密相关的类拆分成 控制层实现层 两个相互独立的层次结构,从而能在开发时分别使用

在上文的具体案例中,Tickets 属于控制层,People 属于实现层


控制层调用实现层的业务逻辑并与自身的业务逻辑进行组合,形成复杂的逻辑控制对外输出,客户端调用控制层来完成自己的业务

优缺点优点

桥接模式最大的优点在于将一个具有多重功能的系统进行解耦,拆分成相互独立的层次,从而提高系统的可扩展性

桥接模式符合开闭原则,不管新增控制层或实现层的代码都可以很容易实现,而且它们不会相互影响

也符合单一原则,控制层专注于控制层的逻辑处理,实现层专注于实现层的逻辑处理

业务系统在调用时只与控制层交互,不用关心实现层的具体逻辑

缺点

桥接模式的主要缺点是增加了系统的设计与理解难度,并且,想要从一个多重功能中识别到相互独立的层次结构也不是一件容易的事情

适用场景

桥接模式的主要特点是将一个具有多重功能的系统拆分成两个相互独立的层次结构。所以,在识别到一个类具有两个相互独立变化的维度时,可以优先考虑使用该模式

桥接模式也常用于解决由于继承造成的代码侵入问题,在不希望或者不适用于继承的场景下也可以考虑使用该模式

如果想拆分一个复杂庞大的类时,也可以考虑使用该模式,前提是这个类可以拆分成多个相互独立的层次结构

桥接模式在处理跨平台应用、 支持多种类型的数据库服务器或与多个特定种类 (例如云平台和社交网络等) 的 API 供应商协作时会特别有用

与其他模式关系与适配器模式对比

桥接模式常用于系统设计初期,使我们能够将程序的各个部分相互独立,以便于开发

适配器模式常用在已有的程序中,当发现已有的类无法协同工作时可以考虑适配器模式

搭配抽象工厂模式使用

如果由桥接模式定义的控制层只能与特定实现层合作, 在业务系统调用时就会很复杂

可以使用抽象工厂模式 桥接模式,对业务系统隐藏其复杂的实现过程

工厂模式回顾:设计模式(二):工厂模式

搭配生成器模式使用

生成器模式中的导演类负责桥接模式中的控制层工作,各种不同类型的生成器负责桥接模式中的实现层工作

生成器模式回顾:设计模式(三):生成器模式

设计模式不是万能的,只有合理利用设计模式才能写出合理的代码

  • 哪三种发票可以作废(发票必须这样作废)
  • 2024-09-27发票必须这样作废作废发票!5月12日起,发票必须这样作废,否则罚款比税多!最近一段时间,发票新规定,金税四期等等很多的发票问题都在一点点地进行规范改正就说这发票作废吧!一张或者两张发票的作废,就有可能会引来长时间的稽。
  • 陋室铭全文楷书(清姚孟起陋室铭)
  • 2024-09-27清姚孟起陋室铭姚孟起,字凤生,一作凤笙,吴县(江苏苏州)贡生是中国清代的一个书画家,著有《海上墨林、广印人传、清朝书画家笔录、吴门画史》流传于世以书名,正书宗欧阳询,尝临九成宫醴泉铭逼肖隶书略仿陈鸿寿兼治印,得蒋仁。
  • 软尾小矶竿钓鱼方法(它是抛竿阵营的小弟)
  • 2024-09-27它是抛竿阵营的小弟淡水抛竿玩法在国内已成为仅次于传统钓、悬坠钓之后的主力玩法之一在钓鱼运动蓬勃发展的近十年,抛竿的钓技钓法被厂商与钓鱼人运用到了极致,产品方面也得到了细分,如海竿、矶竿、岸筏钓等做为面市最晚的小矶竿近些。
  • 富爸爸富人思维案例(富爸爸穷爸爸全系列)
  • 2024-09-27富爸爸穷爸爸全系列大家好,这里是喜好电竞,爱财富的大锤,今天与您一起学的是富爸爸穷爸爸第一本系列的第五课:富人的投资,这一课主要分为三个部分1.要有足够的勇气2.最重要的资产是我们的头脑3.作为投资者的主要技能1.要有。
  • 宅家必看三部电影 春节宅家观影片单
  • 2024-09-27宅家必看三部电影 春节宅家观影片单再过几天就是兔年春节了有没有像我一样,漫漫长假都宅在家里的?无聊?一点都不!我可是非常期待呀!手头上囤的影视书籍资源,就等着这个假期一次看完!观影指南整理出来了,特点就是:量多!包新!好看!就怕看不完。
  • 书写时代精神,展现后浪风采 书写时代精神歌颂人间大爱
  • 2024-09-27书写时代精神,展现后浪风采 书写时代精神歌颂人间大爱自新冠肺炎疫情暴发以来,中国全民抗疫中涌现出无数可歌可泣的人物和故事让观众在典型故事中找到普遍共鸣,将伟大抗疫精神化作回首凝望时的信心和动力,是抗疫题材电视剧创作的核心纵观已播出的此类剧集,不难发现其。
  • 龙生九子各不同是必然还是偶然(龙生九子细谈)
  • 2024-09-27龙生九子细谈何为“龙生九子”?这句话的原话为“龙生九子不成龙,各有所好”,出自明代徐应秋的《玉芝堂谈荟·龙生九子》,用以比喻同胞兄弟品质,爱好各不相同有关九龙子这一说法最早的出处其实和“凤育九雏”一样出自晋代,炼。
  • 车龄15年以上的桑塔纳值得买吗(全球累计超380万辆)
  • 2024-09-27全球累计超380万辆在我们国内的汽车市场当中,大众汽车在最近几十年创造了很多经典的车像大众捷达,桑塔纳宝来等等被奉为一代人的经典全球累计销量超380万辆1km还不到四毛钱现在捷达一降到底6万起车友说桑塔纳真香但是经典归经。
  • 全球人口大国排行榜(全球人口达到80亿)
  • 2024-09-27全球人口达到80亿按照联合国《世界人口展望2022》报告,今天(2022年11月15日),全球人口达到80亿过去的70年,全球人口增加了三倍之多,但人口的增速在下降据预测,全球人口将在2050年接近100亿,并在此后5。
  • 企管部工作职责和工作制度(企管部与技术部岗位职责)
  • 2024-09-27企管部与技术部岗位职责企管部部长职责1、在常务副总经理的直接领导下,负责对销售订单的接收和整理;根据各车间(包括黄冈)的生产特点,合理分配订单,下达生产任务,保证生产产量最大化2、监督各车间订单生产顺序,严格按企管部下达的。
  • 留一点微笑给自己作文(作文怎么写)
  • 2024-09-27作文怎么写生活是一部永远也读不懂的书,更是为人类而搭起的舞台,人类在上面扮演着各种角色,演绎着各自的喜怒哀乐和悲欢情愁其中,微笑是一门常见的、再平常不过的艺术但是,她可以用无形的力量营造我们生命的凭籍,犹如一盏。
  • 人类历史上的流行传染病(人类历史上最可怕的七大传染病排行)
  • 2024-09-27人类历史上最可怕的七大传染病排行大家好!2020年新型冠状病毒的出现,严重影响了我们的生活就拿春节来说,本来应该是热热闹闹的街道却变得冷冷清清,出现这种现象恐怕也是第一次!在疫情的影响下,我们的出行受到了严重的限制、不能扎堆、不能去。