zoukankan      html  css  js  c++  java
  • 设计模式-桥接模式

    设计模式-桥接模式

    定义

    桥接模式又叫桥梁模式、接口模式或柄体模式。是将抽象的部分和实现的部分分离开来,使它们可以独立变化

    通过组合的方式建立两个类之间的联系,而不是继承。

    属于结构型模式。

    适用场景

    1. 在抽象和具体实现之间需要增加更多的灵活性的场景。
    2. 一个类存在两个独立变化的维度,而这两个维度都需要独立进行扩展。
    3. 不希望使用继承,或者多层继承导致系统类的个数剧增。

    例子

    image

    代码示例:

    UML 类图:
    image

    新建一个IMessage消息接口类,有一个sendMessage 方法:

    /**
     * 消息接口类
     * @author black
     *
     */
    public interface IMessage {
    
        /**
         * 发送消息
         * @param message 消息题
         * @param recvUser 接收者
         */
        void sendMessage(String message, String recvUser);
    }
    

    根据【消息发送方式】维度,新建邮件消息类:

    package com.black.design.pattern.bridge.general;
    
    /**
     * 邮件消息
     * @author black
     *
     */
    public class EmailMessage implements IMessage {
    
        public void sendMessage(String message, String recvUser) {
            System.out.println("发送邮件【"+message+"】给" + recvUser);
        }
    
    }
    
    

    根据【消息发送方式】维度,新建短信消息类:

    package com.black.design.pattern.bridge.general;
    
    /**
     * 短信消息
     * @author black
     *
     */
    public class SmsMessage implements IMessage {
    
        public void sendMessage(String message, String recvUser) {
            System.out.println("发送短信【"+message+"】给" + recvUser);
        }
    
    }
    
    

    根据【消息类型】维度,新建普通消息类:

    package com.black.design.pattern.bridge.general;
    
    /**
     * 普通消息
     * @author black
     *
     */
    public class NormalMessage implements IMessage {
    
        public void sendMessage(String message, String recvUser) {
            message = "【普通】" + message;
            System.out.println("发送"+message+"给" + recvUser);
        }
    }
    
    

    根据【消息类型】维度,新建紧急消息类:

    package com.black.design.pattern.bridge.general;
    /**
     * 紧急消息
     * @author black
     *
     */
    public class EmergencyMessage implements IMessage {
    
        public void sendMessage(String message, String recvUser) {
            message = "【紧急】" + message;
            System.out.println("发送"+message+"给" + recvUser);
        }
    
    }
    
    
    

    这时候,我想在邮件消息或者短信发送时,将消息的紧急程度加上,于是进行以下改造:

    1. 根据【发送消息方式】抽象出一个抽象类
    2. 抽象类构造方法注入 【消息类型】的IMessage接口类
      改造后的UML 类图:
      image

    其中,AbstractMessage就是一个桥,通过组合方式,引入了同一接口另一个维度。
    改造后代码:

    IMessage 接口类不变:

    package com.black.design.pattern.bridge.general;
    
    /**
     * 消息接口类
     * @author black
     *
     */
    public interface IMessage {
    
        /**
         * 发送消息
         * @param message 消息题
         * @param recvUser 接收者
         */
        void sendMessage(String message, String recvUser);
    }
    
    

    【发送消息方式】维度抽象出一个 AbstractMessage 抽象类,构造方法注入【消息类型】维度 :

    
    package com.black.design.pattern.bridge.general;
    
    /**
     * 作为桥梁引入【消息类型】
     * @author black
     *
     */
    public class AbstractMessage implements IMessage {
      //引入另一变化维度
        private IMessage msgType;
        
        public AbstractMessage(IMessage messageType) {
            this.msgType = messageType;
        }
        
    	//调用【消息类型】纬度的sendMessage方法
        public void sendMessage(String message, String recvUser) {
            msgType.sendMessage(message, recvUser);
        }
    }
    
    

    EmailMessage 类继承 AbstractMessage 类,委托父类进行发送消息:

    package com.black.design.pattern.bridge.general;
    
    /**
     * 发送消息方式-邮件
     * @author black
     *
     */
    public class EmailMessage extends AbstractMessage{
    
        public EmailMessage(IMessage messageType) {
            super(messageType);
        }
    
        public void sendMessage(String message, String recvUser) {
    	// 添加消息发送方式
            message = "邮件【" + message +"】";
            super.sendMessage(message, recvUser);
        }
    
    }
    
    
    

    SmsMessage 类继承 AbstractMessage 类,委托父类进行发送消息:

    
    package com.black.design.pattern.bridge.general;
    
    /**
     * 发送消息方式-短信
     * @author black
     *
     */
    public class SmsMessage extends AbstractMessage{
    
        public SmsMessage(IMessage messageType) {
            super(messageType);
        }
    
        public void sendMessage(String message, String recvUser) {
    	// 添加消息发送方式
            message = "短信【" + message +"】";
            super.sendMessage(message, recvUser);
        }
    }
    
    

    NormalMessage 类不变:

    package com.black.design.pattern.bridge.general;
    
    /**
     * 普通消息
     * @author black
     *
     */
    public class NormalMessage implements IMessage {
    
        public void sendMessage(String message, String recvUser) {
            message = "【普通】" + message;
            System.out.println("发送"+message+"给" + recvUser);
        }
    }
    
    
    

    EmergencyMessage 类不变:

    package com.black.design.pattern.bridge.general;
    /**
     * 紧急消息
     * @author black
     *
     */
    public class EmergencyMessage implements IMessage {
    
        public void sendMessage(String message, String recvUser) {
            message = "【紧急】" + message;
            System.out.println("发送"+message+"给" + recvUser);
        }
    
    }
    
    
    

    测试类:

    package com.black.design.pattern.bridge.general;
    
    public class MessageTest {
    
        public static void main(String[] args) {
            
            //发送普通短信给black
            IMessage normalMsg = new  NormalMessage();
            IMessage sms =  new SmsMessage(normalMsg);
            sms.sendMessage("吃饭了吗?","black");
            
             //发送紧急邮件给black
            IMessage emergencyMsg = new EmergencyMessage();
            IMessage email =  new EmailMessage(emergencyMsg);
            email.sendMessage("赶紧回来吃饭!","black");
        }
    }
    
    
    

    测试结果:

    发送【普通】短信【吃饭了吗?】给black
    发送【紧急】邮件【赶紧回来吃饭!】给black
    
    

    最后,可能发现,这个例子和【装饰器】模式很像,但是仔细看看会发现,【装饰器】模式是通过继承,而【桥接】模式是通过组合模式。

    优点

    1. 分离抽象部分和具体实现部分
    2. 提高系统扩展性
    3. 符合开闭原则
    4. 符合合成复用原则

    缺点

    1. 增加系统理解与设计难度
    2. 需要正确识别系统中两个独立变化的维度

    本文来自博客园,作者:不安分的黑娃,转载请注明原文链接:https://www.cnblogs.com/lihw-study/p/15158821.html

  • 相关阅读:
    Permutation Sequence
    Anagrams
    Unique Binary Search Trees II
    Interleaving String
    Longest Substring Without Repeating Characters
    Sqrt(x)
    Maximum Product Subarray
    Jump Game II
    Container With Most Water
    C结构体的初始化和赋值
  • 原文地址:https://www.cnblogs.com/lihw-study/p/15158821.html
Copyright © 2011-2022 走看看