. The bridge mode of design pattern research under net

Source: Internet
Author: User
Tags abstract inheritance log connect client
Design

   Overview

In software systems, some types, due to their own logic, have a change of two or more dimensions, so how to deal with this "multidimensional change"? How can you use object-oriented technology to make this type easily change in multiple directions without introducing additional complexity? This is going to use bridge mode.

   Intent

Separate the abstract parts from the implementation parts so that they can be changed independently. [GOF "Design pattern"]

Structure diagram


Figure 1 Bridge pattern structure diagram

   Examples of Life

The bridging pattern separates the abstract part from its implementation, enabling them to change independently. An ordinary switch-controlled electric light, electric fan, etc. are examples of bridging. The purpose of the switch is to turn the device on or off. The actual switch can be a simple two-knife zipper switch, or it can be an dimming switch.

  
Figure 2 Bridge object graph using an electronic switch example

   Bridging mode explanation

In the creation pattern, I have mentioned abstraction and implementation, abstractions should not rely on specific implementation details, implementation details should rely on abstraction. Look at the picture below:

  
Figure 3 Abstraction should not depend on implementation details

In this case, if the abstract B is stable and the details B changes, then the create pattern is used to solve the problem. But if the abstract B is also unstable, but also changes, how to solve it? This is going to take bridge mode.

We still use the example of logging tool to illustrate bridge mode. Now we're going to develop a common logging tool that supports two ways of database record DatabaseLog and text file recording FileLog, while it can run in. NET platform, or it can run on the Java platform.

According to our design experience, different logging methods should be treated as separate objects, and a base class log is abstracted for the logging class, and different logging methods inherit from the base class:

  
Figure 4 Log class structure diagram

The implementation code is as follows:

Public abstract class Log
{
public abstract void Write (string log);
}
public class Databaselog:log
{
public override void Write (string log)
{
//...... Log Database
}
}

public class Textfilelog:log
{
public override void Write (string log)
{
//...... Log Text File
}
}

In addition, considering the logging of different platforms, the way to manipulate the database and write to the text file may not be the same, for different logging methods, we need to provide a variety of different platform implementation, the above class to do further design to get the following structure diagram:

  
Figure 5

The implementation code is as follows:

public class Ndatabaselog:databaselog
{
public override void Write (string log)
{
//...... (. NET platform) Log Database
}
}

public class Jdatabaselog:databaselog
{
public override void Write (string log)
{
//...... (Java Platform) Log Database
}
}
public class Ntextfilelog:textfilelog
{
public override void Write (string log)
{
//...... (. NET platform) Log Text File
}
}
public class Jtextfilelog:textfilelog
{
public override void Write (string log)
{
//...... (Java Platform) Log Textfile
}
}

There is no error in this design now, and if we are going to introduce a new way of recording the XML file, the class diagram above will become:

  
Figure 6

As shown in the blue section of the figure, we added a subclass that inherits from the log base class without modifying other subclasses, which also conforms to the open-closed principle. If we introduce a new platform, such as the logging tool we are developing now, we need to support the Borland platform, then the class structure becomes:

  
Figure 7

Again, we haven't changed anything, just added two subclasses that inherit from DatabaseLog and Textfilelog, which is also consistent with the open-closed principle.

But we say this design is fragile, careful analysis can be found that it still has a lot of problems, first of all, it follows the open-closed principle, while violating the single principle of the class of responsibility, that is, a class has only one reason for its change, and there are two reasons for the log class changes, That is, the change of logging mode and the change of log record platform; followed by a lot of repetitive code, different logging methods on different platforms will also have a part of the code is the same; again, the structure of the class is too complex, the inheritance relationship is too much, difficult to maintain, the last most fatal point is the extensibility is too poor. The changes that we analyze above are just along a certain direction, and if the changes change along the way of logging and two different platforms, we will see that the structure of the class is rapidly becoming larger.

Now it's time for bridge mode to take off and we need to decouple these two directions and change the strong coupling between them into weak connections. We treat the logging mode and the implementation on different platforms as two separate parts, and for logging, the class structure diagram is still:

  
Figure 8

Now we introduce another abstract class Implog, which is the base class for logging on the implementation of different platforms, as shown in the following structure:

  
Figure 9

The implementation code is as follows:

Public abstract class Implog
{
public abstract void Execute (string msg);
}
public class Nimplog:implog
{
public override void Execute (String msg)
{
//...... . NET Platform
}
}

public class Jimplog:implog
{
public override void Execute (String msg)
{
//...... Java Platform
}
}

In this case, for logging mode and different running platform of these two classes can be independent of the change, we have to do is to connect the two parts. So how do you connect? Here, Bridge uses a combination of objects, the class structure diagram is as follows:

  
Figure 10

The implementation code is as follows:

Public abstract class Log
{
protected Implog implementor;
Public Implog Implementor
{
set {implementor = value;}
}
public virtual void Write (string log)
{
Implementor. Execute (log);
}
}

public class Databaselog:log
{
public override void Write (string log)
{
Implementor. Execute (log);
}
}
public class Textfilelog:log
{
public override void Write (string log)
{
Implementor. Execute (log);
}
}

It can be seen that, through the combination of objects, the bridge model changes the inheritance relationship between the two roles to the coupling relationship, so that the two can be Conghonzjo independently of each other, which is also the intention of the bridge model. Let's take a look at how the client uses:

Class APP
{
public static void Main (string[] args)
{
//. NET platform under the database Log
Log DBLog = new DatabaseLog ();
DBLog. Implementor = new Nimplog ();
DBLog. Write ();
Text File Log under the Java platform
Log Txtlog = new Textfilelog ();
Txtlog. Implementor = new Jimplog ();
Txtlog. Write ();
}
}
Some may worry that this does not add to the coupling between client programs and specific logging methods. In fact, such a worry is not necessary, because this coupling is caused by the creation of objects, can be used to create patterns to solve, is not what we discussed here.

Finally, let's consider a question, why does the bridge model use object composition instead of inheritance? If you are using inheritance, the log class, the Implog class are interfaces, and the class structure diagram is as follows:

  
Figure 11

The implementation code is as follows:

public class Ndatabaselog:databaselog, Iimplog
{
//......
}
public class Jdatabaselog:databaselog, Iimplog
{
//......
}
public class Ntextfilelog:textfilelog, Iimplog
{
//......
}
public class Jtextfilelog:textfilelog, Iimplog
{
//......
}
As shown in the blue section of the figure above, they have both logging and interface iimplog characteristics that violate the single responsibility principle of classes in object-oriented design principles, and a class should have only one reason to cause it to change. Therefore, the adoption of bridge model is often more than the adoption of a better scheme. Speaking of which, we should have some understanding of bridge mode? If there are two different directions in the development of the criss-cross changes, should be able to think of the bridge model, of course, sometimes although there are two changes in direction, but in a certain direction the change is not very intense time, Bridge mode is not always used.

   Effect and realization Essentials

1.Bridge mode uses the "Combinatorial relationship between objects" to decouple the intrinsic binding relationship between abstraction and implementation, allowing abstractions and implementations to evolve along their respective dimensions.

2. The so-called abstraction and realization along the respective dimensions of the changes, that is, "subclass" them, after the various subclasses, they can be arbitrary, so as to obtain different models on different platforms.

3.Bridge patterns are sometimes similar to multiple inheritance schemes, but multiple inheritance schemes often violate the single responsibility principle of a class (that is, the reason a class has only one change), and the reusability is rather poor. Bridge mode is a better solution than multiple inheritance schemes.

The application of 4.Bridge mode is generally in "two very strong change dimensions", sometimes even if there are two different dimensions, but the change dimension of a certain direction is not drastic--in other words, two changes will not lead to criss-cross, not necessarily use bridge mode.

   Applicability

Bridge mode should be used in the following cases:

1. If a system needs to add more flexibility between the abstraction and materialization roles of the component, avoid establishing static links between the two levels.

2. Any change in the design requirements to implement the role should not affect the client, or the implementation of the role changes to the client is completely transparent.

3. An artifact has more than one abstract role and an implementation role, and the system requires dynamic coupling between them.

4. Although there is no problem in using inheritance in the system, the design requirements need to be managed independently because of the need for an independent change in the abstraction and materialization roles.

Summarize

Bridge mode is a very useful model, and very complex, it is well in line with the open-closed principle and priority to use objects, rather than inherit these two object-oriented principles.

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.