兄弟们,想写出好的Java代码,设计模式还是要烂熟于心的鸭。
仔细理解实践每一种模式,体会设计模式之美。
一、 模式定义
桥接模式又叫接口模式。
说白了就是将变化的部分抽象成接口,桥接模式是结构型模式,着重看下 结构上是如何实现的和应用场景。
说到面向接口编程,那场景可多了去了,在基于Spring的工程架构中,是不是到处都是接口,可以看做是一种退化的桥接模式。
桥接模式即将抽象部分与它的实现部分分离开来,使他们都可以独立变化。
二、 模式结构
下图是桥接模式的UML结构图:
桥接模式主要包含如下几个角色:
Abstraction:抽象类。
RefinedAbstraction:扩充抽象类。
Implementor:实现类接口。
ConcreteImplementor:具体实现类 。
三、 模式实现
支付平台的对接,支付品牌:支付宝和微信,支付方式:密码、指纹、人脸
- /**
- * @Project fighting-core
- * @Description 支付品牌抽象类
- * @Author lvaolin
- * @Date 2022/8/14 下午10:07
- */
- public abstract class AbstractPay {
- private Payment payment;//桥接支付方式的关键部分
-
-
- public AbstractPay(Payment payment) {
- this.payment = payment;
- }
-
-
- public abstract boolean pay();
-
-
- public Payment getPayment() {
- return payment;
- }
- }
-
-
- /**
- * @Project fighting-core
- * @Description 阿里支付
- * @Author lvaolin
- * @Date 2022/8/14 下午10:11
- */
- public class AliPay extends AbstractPay {
- public AliPay(Payment payment) {
- super(payment);
- }
-
-
- @Override
- public boolean pay() {
- System.out.println("阿里支付开始");
- super.getPayment().method();
- System.out.println("阿里支付成功");
- return true;
- }
- }
-
-
- /**
- * @Project fighting-core
- * @Description 微信支付
- * @Author lvaolin
- * @Date 2022/8/14 下午10:11
- */
- public class WeXinPay extends AbstractPay{
- public WeXinPay(Payment payment) {
- super(payment);
- }
-
-
- @Override
- public boolean pay() {
- System.out.println("微信支付开始");
- super.getPayment().method();
- System.out.println("微信支付成功");
- return true;
- }
- }
- /**
- * @Project fighting-core
- * @Description 支付方式接口
- * @Author lvaolin
- * @Date 2022/8/14 下午10:08
- */
- public interface Payment {
- void method();
- }
-
-
- /**
- * @Project fighting-core
- * @Description 人脸支付
- * @Author lvaolin
- * @Date 2022/8/14 下午10:13
- */
- public class PaymentFace implements Payment {
- @Override
- public void method() {
- System.out.println("人脸验证通过");
- }
- }
-
-
- /**
- * @Project fighting-core
- * @Description 指纹支付
- * @Author lvaolin
- * @Date 2022/8/14 下午10:13
- */
- public class PaymentFingerprint implements Payment {
- @Override
- public void method() {
- System.out.println("指纹验证通过");
- }
- }
-
-
- /**
- * @Project fighting-core
- * @Description 密码支付
- * @Author lvaolin
- * @Date 2022/8/14 下午10:13
- */
- public class PaymentPassword implements Payment {
- @Override
- public void method() {
- System.out.println("密码验证通过");
- }
- }
- /**
- * @Project fighting-core
- * @Description 客户端测试
- * @Author lvaolin
- * @Date 2022/8/14 下午10:21
- */
- public class Client {
- public static void main(String[] args) {
- AbstractPay pay1 = new AliPay(new PaymentFace());
- pay1.pay();
-
-
- AbstractPay pay2 = new WeXinPay(new PaymentPassword());
- pay2.pay();
-
-
- }
- }
-
-
- 阿里支付开始
- 人脸验证通过
- 阿里支付成功
-
-
- 微信支付开始
- 密码验证通过
- 微信支付成功
四、 模式优缺点
优点
1、分离抽象接口及其实现部分。提高了比继承更好的解决方案。
2、桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
3、实现细节对客户透明,可以对用户隐藏实现细节。
缺点
1、桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
2、桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
五、 模式使用场景
1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
应用举例:
1)电脑配置和电脑品牌是两个维度的变化
2)图形和颜色是两个维度的变化
3)支付品牌和支付方式是两个维度的变化
4)报警方式(短信、邮件、企微、QQ群)与事件等级(一般、重要、紧急)是两个维度的变化
5)奶茶的口味与杯子容量 是两个维度的变化
6)鸡蛋灌饼品牌与鸡蛋灌饼配置是两个维度的变化
7)业务种类的变化与数据库品牌的变化是两个维度的变化
8)汽车种类与汽车颜色的变化是两个维度的变化
9)汽车品牌与汽车配置的变化是两个维度的变化
10)电脑种类(笔记本、台式机、服务器)与电脑品牌的变化
11)银行转账(网银、ATM、柜台)与卡级别(金卡、银卡、铜卡)的变化
12)老师(张三、李四、王五)与课程(数学、英语、语文)是两个维度的变化
六、 模式总结
1、桥接模式实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。
2、对于两个独立变化的维度,使用桥接模式再适合不过了。
3、对于"具体的抽象类"所做的改变,是不会影响到客户。