The bridge model of Java and pattern

Source: Internet
Author: User

Bridge mode is the structure pattern of the object. Also known as the handle body (Handle and body) mode or interface (Interface) mode. The bridge model is intended to "decouple abstraction (abstraction) from implementation (implementation) so that they can vary independently".

The purpose of bridge mode

  While bridge mode is not a highly used pattern, familiarity with this pattern is useful for understanding object-oriented design principles, including the "open-close" principle and the combination/aggregation multiplexing principle. Understanding these two principles helps to form the right design ideas and develop a good design style.

The bridge model is intended to "decouple abstraction (abstraction) from implementation (implementation) so that they can vary independently". This is a short sentence, but the first person to read this sentence is likely to think for a long time and do not understand the meaning.

This sentence has three key words, namely abstraction, realization and decoupling. Understanding the concepts represented by these three words is the key to understanding the purpose of bridge patterns.

    • Abstraction of

Extracting common and essential features from many things, and discarding their non-essential features, is abstraction. such as apples, bananas, pears, peaches, and so on, their common characteristic is fruit. The process of drawing fruit concept is an abstract process. To be abstract, comparisons must be made, and there is no comparison to find the parts that are essentially common. Common characteristics are those features that distinguish a kind of thing from his class, and these distinguishing features are also called essential features. So the common feature of extracting things is to extract the essential characteristics of things and discard the non-essential features. So the process of abstraction is also a cropping process. In the abstract, the same and different, it is decided from what angle to abstract. The abstract angle depends on the purpose of the analysis problem.

Typically, a group of objects, if they have the same characteristics, can be described by a common class. If some classes have the same characteristics, they can often be described by a common abstract class.

    •   Realization of

The concrete implementation of abstraction is realization.

An instance of a class is an instantiation of this class, and a concrete subclass is an instantiation of its abstract superclass.

    •   de-coupling

The so-called coupling is a strong association of the behavior of two entities. and the strong association is removed, is the coupling of liberation, or decoupling. In this case, decoupling means freeing the coupling between abstraction and implementation, or changing the strong association between them into weak associations.

The so-called Strong Association, which is determined in the compile time, cannot be dynamically changed at runtime, so-called weak correlation is the association that can be dynamically determined and can be dynamically changed during the run time. Obviously, in the Java language, an inheritance relationship is strongly associative, whereas an aggregation relationship is a weak association.

Changing the inheritance relationship between the two roles to an aggregation relationship is the change of the strong association between them into a weak association. Therefore, the so-called decoupling in bridge mode refers to the use of aggregation relationships rather than inheritance relationships between abstractions and implementations of a software system, so that they can vary relatively independently. This is the purpose of bridge mode.

Structure of the bridge pattern

Shown is a schematic diagram of the system that implements the bridge pattern:

As you can see, this system contains two hierarchical structures:

Abstract hierarchical structure composed of abstract roles and modified abstract roles.

  Second, the implementation of the role and two specific implementation of the role of the implementation of the hierarchical structure.

  The roles involved in bridge mode are:

abstract (abstraction) role: abstract The given definition and save a reference to the implemented object.

Fix abstract (refinedabstraction) roles: extend abstract roles, change and modify the definition of the parent class for abstraction.

implementation-implementor role: This role gives the interface to the implementation of the role, but does not give a specific implementation. It must be noted that this interface is not necessarily the same as the interface definition of the abstract role, in fact, the two interfaces can be very different. The implementation role should only give the underlying operation, and the abstract role should give only a higher level of operation based on the underlying operation.

implementation-specific (concreteimplementor) role: This role gives a concrete implementation of the implementation of the role interface.

The abstract character is like a handle to a water cup, while the realization of the role and the specific implementation of the role is like a cup of water cup body. The handle controls the cup body, which is the source of this pattern alias "handle Body".

An object is a wrapper over the behavior, and the behavior is implemented by the method. In this schematic system, classes in the abstract hierarchical structure encapsulate the operation () method, whereas classes in the implementation hierarchy encapsulate the Operationimpl () method. Of course, there are often more than one method in the actual system.

Methods in an abstract hierarchical structure implement their own functionality by delegating to the corresponding implementation object, which means that the abstract role can achieve the purpose of dynamically transforming its own functionality by delegating to different implementation objects.

Source

Abstract the role class, which declares a method operation (), and gives its implementation. This implementation is achieved by delegating (calling the Operationimpl () method) to the implementation of the object.

Public abstract class Abstraction {        protected implementor impl;        Public abstraction (Implementor impl) {        This.impl = impl;    }    Example method public    void operation () {                impl.operationimpl ();    }}

Correcting abstract roles

public class Refinedabstraction extends abstraction {public        refinedabstraction (implementor impl) {        super ( IMPL);    }    Other methods of operation public    void Otheroperation () {            }}

Implementing roles

Public abstract class Implementor {    /**     * Example method to implement some specific functions required by the abstract     *    /public abstract void Operationimpl () ;}

Specific implementation of the role

public class Concreteimplementora extends Implementor {    @Override public    void Operationimpl () {        //specific action    }}
public class Concreteimplementorb extends Implementor {    @Override public    void Operationimpl () {        ///specific operation c15/>}}

In general, each method in an implementation role should have one of the methods in an abstract role corresponding to it, but not necessarily in turn. In other words, the interface of the abstract role is wider than the interface of the implementing role. Abstract roles can provide other methods in addition to the methods associated with implementing roles, while implementation roles tend to exist only to implement the related behavior of the abstract role.

Usage Scenarios

Consider such an actual business function: send a prompt message. Basically all systems with business process processing will have such a function, such as the OA has not finished processing files, you need to send a message to prompt him.

From the business perspective, the message is divided into ordinary messages, expedited messages and express messages of various, different message types, business function processing is not the same, such as expedited message is added to the message expedited, and the express message in addition to add urgent, will also make a hurried record, how long does not finish will continue to urge; from the means of sending messages, And there are short messages in the system, mobile phone messages, mail and so on.

Solutions that do not use patterns

Implement send normal message

Consider the implementation of a simple version of the first, for example, the message is only the implementation of sending ordinary messages, the way to send only the system to implement short messages and messages. Other features, wait until this version is complete, and then continue adding.

Source

Unified interface for messages

Public interface Message {    /**     * sends messages     * @param message content to be sent     * @param  the recipient    of the touser message */ public void Send (String message, String touser);}

Intra-system Short message sample class

public class Commonmessagesms implements Message {    @Override public    void Send (String Message, String touser) {
   SYSTEM.OUT.PRINTLN ("Use the method of short message within the system, send Message '" +message+ "' to" +touser);}    }

Mail message Sample Class

public class Commonmessageemail implements message{    @Override public    void Send (String Message, String touser) { C8/>SYSTEM.OUT.PRINTLN ("Use message Short message method, send Message '" +message+ "' to" +touser);    }}
Implement send expedited Message

There are two ways to send expedited messages, in-system short messages and message methods. However, the implementation of the expedited message is different from the normal message, the expedited message will automatically add an expedited message, and then send the message, and the expedited message will provide a method of monitoring, so that the client can at any time in this way to understand the progress of the expedited message processing. For example, if the appropriate person receives this information, the corresponding processing work has been carried out. Therefore, the expedited message needs to expand a new interface, in addition to the basic ability to send messages, but also need to add monitoring capabilities.

Source

Interface for expedited messages

Public interface Urgencymessage extends message {    /**     * Monitor the processing of the specified message     * @param messageId  Monitored messages number     * @ The    processing status of the message monitored by return     *    /public Object watch (String messageId);

Example class for expedited short messages in the system

public class Urgencymessagesms implements Urgencymessage {    @Override public    Object Watch (String messageId) { c12/>//gets the status of the message based on the message ID, organizes it into a monitored data object, and returns a return of        null;    }    @Override public    void Send (String message, String touser) {                message = "Expedited:" + message;        SYSTEM.OUT.PRINTLN ("Use the method of short message within the system, send Message '" +message+ "' to" +touser);}    }

Message Expedited Short Message sample class

public class Urgencymessageemail implements Urgencymessage {    @Override public    Object Watch (String messageId) { c2/>//gets the status of the message based on the message ID, organizes it into a monitored data object, and returns a return of        null;    }    @Override public    void Send (String message, String touser) {                message = "Expedited:" + message;        SYSTEM.OUT.PRINTLN ("Use message Short message method, send Message '" +message+ "' to" +touser);    }}
Implement send Express message

The urgent message does not need to look at the processing process, only did not complete, the direct urge, that is, for the express message, in the ordinary message processing based on the need to add the urge to function.

Looking at the system diagram above, it is obvious that it is very inconvenient to extend the message processing by this kind of inheritance. In the case of expedited message processing, it is necessary to implement both short message and message processing in the system, because the business processing may be different, and in the implementation of the express message processing, it is necessary to implement two kinds of processing methods of SMS and mail within the system. This means that each time you expand the message processing, you have to implement both of these processing methods, this is not complete, if you want to add a new implementation way?

Add how to send a phone message

If you want to add a new way of sending a message, you need to add the processing of the sending phone message in each abstract concrete implementation. In other words, the sending of ordinary messages, expedited messages and the processing of express messages can be sent through the mobile phone.

  

Using inheritance to extend the implementation of the way, there is an obvious disadvantage, the extension of the type of message is not easy. Different kinds of messages have different business, that is, there are different implementations, in this case, each kind of message needs to implement all the different ways of sending messages. Even more frightening, if you want to add a new way of sending a message, then all the message types will be required to join the implementation of this new way of sending.

So how can we achieve both the function and the flexibility to expand it?

Use bridge mode to solve problems

According to the functional requirements of the business, business changes have two dimensions, a dimension is abstract message, including ordinary messages, expedited messages and express messages, these abstract messages themselves have a certain relationship, the expedited message and the express message will extend the ordinary message, the other dimension is in the specific way of sending messages, including short messages within the system, messages and SMS, these methods are equal and can be switched in a way.

  

  

The root cause of the problem now is that the abstraction and implementation of the message are mixed together, which leads to a change in the latitude that causes the other latitude to change accordingly, making the program very difficult to extend.

To solve this problem, it is necessary to separate the two latitudes, that is, to separate the abstract and implementation parts so that they are independent, so that independent changes can be made, so that the expansion is simple. The abstract part is the function of each message type, and the implementation part is the way of sending the message. According to the structure of the bridge pattern, the interface is defined separately for the abstract part and the implementation part, and then it can be implemented separately.

  

Source

Abstract Message Class

Public abstract class Abstractmessage {    //holds an implementation part of the object    messageimplementor impl;    /**     * Construction method, the object that is passed into the implementation part     * @param  The object of the Impl implementation part *     /public    abstractmessage (Messageimplementor impl) {        This.impl = impl;    }    /**     * Send a message, delegate to the implementation part of the method     * @param message    to send the content of the messages     * @param    the recipient of the Touser message *    * Public void SendMessage (String message, String touser) {        this.impl.send (message, touser);}    }

General Message Class

public class Commonmessage extends Abstractmessage {public    commonmessage (Messageimplementor impl) {        super ( IMPL);    }    @Override public    void SendMessage (String message, String touser) {        //For normal messages, call the parent class method directly, send a message        to Super.sendmessage (message, touser);}    }

Expedited Message Class

public class Urgencymessage extends Abstractmessage {public    urgencymessage (Messageimplementor impl) {        super ( IMPL);    }    @Override public    void SendMessage (String message, String touser) {        message = "Expedited:" + message;        Super.sendmessage (message, touser);    }    /**     * Expands its own new functionality to monitor the processing status of a message     * @param messageId    Monitored message number     * @return the    processing status    of the monitored messages */ public Object Watch (String messageId) {        //Gets the state of the message based on the message ID, organizes it into a monitored data object, and returns a return of        null;}    }

Implementing a unified interface for sending messages

Public interface Messageimplementor {    /**     * Send Message     * @param message content to be sent     * @param touser  Recipient of Message     *    /public void Send (String message, String touser);}

Implementation classes for short messages within the system

public class Messagesms implements Messageimplementor {    @Override public    void Send (String message, String Touser {                System.out.println ("Use the method of short message within the system, send Message '" +message+ "' to" +touser);}    }

The implementation class of message short message

public class Messageemail implements Messageimplementor {    @Override public    void Send (String message, string Touser) {        System.out.println ("Use message Short message method, send Message '" +message+ "' to" +touser);}    }

Client class

public class Client {public    static void Main (string[] args) {        //Create concrete Implementation Object        Messageimplementor Impl = new Messa Gesms ();        Create a generic Message object        abstractmessage msg = new  commonmessage (impl);        Message.sendmessage ("Overtime request", "Li Total");                Switch the implementation mode to mail and resend        impl = new Messageemail ();        Create an expedited Message object        : message = new Urgencymessage (impl);        Message.sendmessage ("quick instalment of overtime requests", "Li");}    

Observing the above example will find that the use of bridge mode to achieve, the abstraction and implementation of the partial separation, can be independent of each other, without affecting each other. Therefore, the addition of new message processing (express message) in the abstract part has no effect on the implementation of the sending message, which in turn increases the way the message is sent (SMS message), which has no effect on the message processing part.

Advantages of bridge mode

separating abstraction and implementation parts

The bridge pattern separates the abstract and the implementation parts, thus greatly providing the flexibility of the system. To separate the abstract and implementation parts, define the interfaces separately, which helps to layer the system, resulting in a better structured system.

Better Extensibility

  The bridge mode allows the abstraction and implementation to be expanded independently, without affecting each other, thus greatly improving the scalability of the system.

The use of bridge mode in Java

A very typical example of bridge mode in Java applications is the JDBC driver. JDBC provides a common interface for all relational databases. An application dynamically selects a suitable drive and then sends instructions to the database engine through the drive. This process is to delegate the behavior of the abstract role to the process of implementing the role.

Abstract roles can issue query directives against any database engine, because abstract roles do not directly interact with the database engine, and the JDBC Drive is responsible for the underlying work. Because of the presence of a JDBC drive, the application system can evolve independently of the details of the database engine, and the database engine can evolve independently of the details of the application system. The two independent hierarchy is shown, the left side is the JDBC API hierarchy, and the right is the JDBC drive hierarchy. The application is built on the JDBC API.

The application system, as a hierarchical structure, is relatively independent of the hierarchical structure of the JDBC driver, and there is no static strong association between them. The application system interacts with the JDBC driver through delegation, which is an example of a bridge pattern.

This architecture of JDBC separates the abstract from the concrete, so that both the abstract and the concrete parts can be expanded independently. For an application, a different driver can be used to allow the program to operate on a different database without changing the application, enabling porting on different databases, and for drivers, implementing different drivers for the database without impacting the application.

The bridge model of Java and pattern

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.