Java设计模式9:桥接模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_37591536/article/details/83027813

一、桥接模式:

桥接模式是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

二、示例代码:

先来考虑下如下场景:

发送消息功能。基本上所有带业务流程处理的系统都会有这样的功能,比如OA上有尚未处理完毕的文件,需要发送一条消息提示他。从业务上看,消息又分为普通消息、加急消息多种,不同的消息类型,业务功能处理是不一样的,比如加急消息是在消息上添加加急。从发送消息的方式上看,又有系统内消息、手机消息、邮件等。

先来看下不使用设计模式情况下实现如上功能,直接上代码:

先创建统一消息接口

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 14:58
 *    @desc   : 消息的统一接口
 *    @version: 1.0
 * </pre>
 */
public interface Message {

    void send (String message,String toName);
}

系统方式发送普通消息的实现类:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:02
 *    @desc   : 系统内普通消息
 *    @version: 1.0
 * </pre>
 */
public class CommonMessageSMS implements Message {
    @Override
    public void send(String message, String toName) {
        System.out.println(String.format("使用系统发送消息方式,发送消息 %s 给 %s",message,toName));
    }
}

邮件方式发送普通消息的实现类:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:05
 *    @desc   : 使用邮件的方式发送普通消息
 *    @version: 1.0
 * </pre>
 */
public class CommonMessageEmail implements Message {
    @Override
    public void send(String message, String toName) {
        System.out.println(String.format("使用邮件发送普通消息方式,发送消息 %s 给 %s",message,toName));
    }
}

那么这个时候我们需要实现加急消息的功能,同样有系统和邮件两种消息方式。

我们为了简化业务,加急消息是在普通消息内容前加上“加急”字符串。

系统方式发送加急消息:

**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:10
 *    @desc   : 系统内加急消息实现类
 *    @version: 1.0
 * </pre>
 */
public class UrgentMessageSMS implements Message {
    @Override
    public void send(String message, String toName) {
        message = "加急" + message;
        System.out.println(String.format("使用系统内发送消息方式,放送消息 %s 给 %s",message,toName));
    }
}

邮件方式发送加急消息:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:13
 *    @desc   : 使用邮件方式发送加急消息
 *    @version: 1.0
 * </pre>
 */
public class UrgentMessageEmail implements Message {
    @Override
    public void send(String message, String toName) {
        message = "加急" + message;
        System.out.println(String.format("使用邮件发送消息方式,发送内容", message, toName));
    }
}

观察上面实现消息功能的代码,用这种直接实现接口的方式来拓展消息处理,会非常不方便。实现加急消息处理的时候,必须实现系统内消息和邮件两种处理方式。如果我们又必须要来再实现第三种消息类型:特急消息发送,又必须实现系统内消息和邮件两种处理方式。这意味着,以后每次拓展一次消息类型,都必须要实现这两种消息处理方式,这还不算完,如果要添加新的处理方式呢?如果手机发送的方式?那么我们就必须增加普通,加急,特急三种实现类。在这种情况下,每一种类的消息,需要实现所有不同的消息发送方式。更可怕的是,如果要新加入一种消息的发送方式,那么会要求所有的消息种类都有加入这种新的发送方式的实现。

三、使用桥梁模式来解决问题

首先同样的统一消息请求接口:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 14:58
 *    @desc   : 消息的统一接口
 *    @version: 1.0
 * </pre>
 */
public interface Message {

    void send (String message,String toName);
}

抽象消息类型类:

**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:40
 *    @desc   : 抽象消息类
 *    @version: 1.0
 * </pre>
 */
public abstract class AbstractMessage{

    private Message message;

    public AbstractMessage(Message message){
        this.message = message;
    }

    public void sendMessage (String message,String toName){
        this.message.send(message,toName);
    }

}

普通消息实现类:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:47
 *    @desc   : 普通消息实现类
 *    @version: 1.0
 * </pre>
 */
public class CommonMessage extends AbstractMessage{

    public CommonMessage(Message message){
        super(message);
    }

    @Override
    public void sendMessage(String message, String toName) {
        super.sendMessage(message,toName);
    }
}

加急消息实现类:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:53
 *    @desc   : 加急消息实现类
 *    @version: 1.0
 * </pre>
 */
public class UrgencyMessage extends AbstractMessage {
    public UrgencyMessage(Message message) {
        super(message);
    }

    @Override
    public void sendMessage(String message, String toName) {
        message = "加急" + message;
        super.sendMessage(message,toName);
    }
}

系统消息:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:02
 *    @desc   : 使用系统方式发送消息
 *    @version: 1.0
 * </pre>
 */
public class MessageSMS implements Message {
    @Override
    public void send(String message, String toName) {
        System.out.println(String.format("使用系统发送消息方式,发送消息 %s 给 %s",message,toName));
    }
}

邮件消息:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:05
 *    @desc   : 使用邮件的方式发送消息
 *    @version: 1.0
 * </pre>
 */
public class MessageEmail implements Message {
    @Override
    public void send(String message, String toName) {
        System.out.println(String.format("使用邮件发送消息方式,发送消息 %s 给 %s",message,toName));
    }
}

客户端测试:

/**
 * <pre>
 *    @author : orange
 *    @e-mail : [email protected]
 *    @time   : 2018/10/12 15:57
 *    @desc   :
 *    @version: 1.0
 * </pre>
 */
public class Client {
    public static void main(String[] args) {
        Message message = new MessageSMS();
        AbstractMessage abstractMessage = new CommonMessage(message);
        abstractMessage.sendMessage("呵呵呵", "老板");


        message = new MessageEmail();
        abstractMessage = new UrgencyMessage(message);
        abstractMessage.sendMessage("嘿嘿嘿","女朋友");

    }
}

四、总结:

个人理解:桥接是一个接口,它与一方应该是绑定的,也就是解耦的双方中的一方必然是继承这个接口的,这一方就是实现方,而另一方正是要与这一方解耦的抽象方,如果不采用桥接模式,一般我们的处理方式是直接使用继承来实现,这样双方之间处于强链接,类之间关联性极强,如要进行扩展,必然导致类结构急剧膨胀。采用桥接模式,正是为了避免这一情况的发生,将一方与桥绑定,即实现桥接口,另一方在抽象类中调用桥接口(指向的实现类),这样桥方可以通过实现桥接口进行单方面扩展,而另一方可以继承抽象类而单方面扩展,而之间的调用就从桥接口来作为突破口,不会受到双方扩展的任何影响。

猜你喜欢

转载自blog.csdn.net/weixin_37591536/article/details/83027813