Policy mode vs Bridge Mode

Source: Internet
Author: User

This is finally met by our friends. The strategic model is so similar to the bridge model, it is simply a twin brother. It takes a lot of intelligence to separate the two. Let's look at the general class diagrams of the two, as shown in figure 33-1.


Figure 33-1 General class diagram of policy mode (left) and bridge mode (right)

What? Didn't you see that the two are very similar? If you change the environment role of the Policy mode to an abstract class and add an implementation class, or the abstract role of the bridge mode is not implemented, you can only modify the abstract role, what are the differences between the two class diagrams? Same, exactly the same! It is precisely because of the existence of similar scenarios that the two are often confused in actual applications. Let's give an example to illustrate the differences between the two.

We should all know that there are two formats for mail: Text mail and HTML mail. Only simple text information can be found in text mail, in hypertext mail, complex texts (with color, Font, and other attributes), images, and videos can be displayed. If you use Foxmail mail client, you should have a profound experience, I saw an email, huh? You forgot to click the "HTML mail" tag. Today's example shows how to send emails in two different formats and how these two modes are used to deal with such scenarios.

33.1.1 send email in policy Mode

The policy mode is used to send emails. We think these two emails are two different encapsulation formats, which are given an email from the sender, recipient, title, and content, encapsulate them in two different formats and then send them. According to this analysis, we found that two different email encapsulation formats are different.AlgorithmThe specific policy mode is two different policies, which is very simple. We can directly apply the policy mode to implement it. first look at the class diagram, as shown in 33-2.

Figure 33-2 mail sending in policy Mode

We have defined a mail template, which has two implementation classes: textmail (Text mail) and htmlmail (hypertext mail), which respectively implement mail encapsulation in two different formats. MailServer is an environment role that accepts a mailtemplate object and sends it out through the Sendmail method. Let's look at the specificCodeFirst, read the abstract email, as shown in code list 33-1.

Code List 33-1 abstract email

 public abstract class mailtemplate {// mail sender private string from; // recipient private string to; // mail title private string subject; // mail content private string context; // pass the mail Information Public mailtemplate (string _ from, string _ to, string _ subject, string _ context) {This. from = _ from; this. to = _ to; this. subject = _ subject; this. context = _ context;} Public String getfrom () {return from;} public void setfrom (string from) {This. from = from;} Public String getto () {return to;} public void setto (string to) {This. to = to;} Public String getsubject () {return subject;} public void setsubject (string subject) {This. subject = subject;} public void setcontext (string context) {This. context = context;} // all emails have public string getcontext () {return context ;}

Strange, right? Why is there no abstract method for an abstract class? What is the significance of setting it to an abstract class? It makes sense. Here we define an abstract class: it has all attributes of the mail, but it is not a specific object that can be instantiated. For example, if you say "Create an email for me" to the email server, the email server will reject it. Why? What emails do you want to produce? In what format? An email is an abstract representation of an email server. It is a descriptive but non-visualized thing. You can say, "I want a mail titled xx, the sender is a message in the text format of XXX. "This is an object that can be instantiated. Therefore, our design generates two sub-classes to embody the mail, in addition, each mail format has different processing methods for the mail content. First, let's look at the text mail, as shown in the code list 33-2.

Code List 33-2 Text emails

 
Public class textmail extends mailtemplate {public textmail (string _ from, string _ to, string _ subject, string _ context) {super (_ from, _ to, _ subject, _ context);} Public String getcontext () {// set the mail format to text/plainstring context = "\ ncontent-type: text/plain; charset = gb2312 \ n "+ super. getcontext (); // At the same time, the mail is base64-encoded. Here, we use a sentence to replace context = context + "\ n. The mail format is text format"; return context ;}}

We overwrite the getcontext method, because to set an email as a text email, a special sign must be added: text/plain. This sentence tells the client to parse the email: "I am an email in text format. Do not parse it incorrectly ". Similarly, hyper-text emails have similar settings, as shown in code listing 3-3.

Code List 33-3 hypertext mail

 
Public class htmlmail extends mailtemplate {public htmlmail (string _ from, string _ to, string _ subject, string _ context) {super (_ from, _ to, _ subject, _ context);} Public String getcontext () {// for Hypertext type, set the mail format to multipart/mixedstring context = "\ ncontent-type: multipart/mixed; charset = gb2312 \ n "+ super. getcontext (); // check the HTML of the email at the same time, whether there is a tag similar to the unclosed context = context + "\ n: hypertext format"; return context ;}}

A superior mail client checks the mail format. For example, if you write a hypertext-format email, the <font> label is added to the content, however, if you forget the </font> end tag, the email sender (that is, the email client) will prompt for correction. Here we use the "mail format: hypertext format.

The two implementation classes implement different algorithms. Given the same sender, recipient, title, and content can produce different mail information. Let's take a look at how the email is sent, as shown in the code list 34-4.

Code List 33-4 email server

 
Public class MailServer {// which email is sent private mailtemplate m; Public MailServer (mailtemplate _ m) {This. M = _ m;} // send the public void Sendmail () {system. out. println ("==== mail message being sent ==="); // sender system. out. println ("Sender:" + M. getfrom (); // recipient system. out. println ("Recipient:" + M. getto (); // The title system. out. println ("mail title:" + M. getsubject (); // The email content system. out. println ("email content:" + M. getcontext ());}}

The email server accepts an email and then calls it to send it.Program. Some readers may ask, why don't we port the Sendmail method into the mail template class? This is also an action of the mail template class. The mail can be sent. Yes, it is indeed an action of the mail. It can be done in this way. There is no special difference between the two, this method is only available from different perspectives. Let's continue to look at the scenario class, as shown in the code list 33-5.

Code List 33-5 scenario classes

 
Public class client {public static void main (string [] ARGs) {// create a text-format email mailtemplate M = new htmlmail ("a@a.com", "B @ B .com ", "aliens attacked the Earth", "the ending is that aliens were swallowed up by Chinese people! "); // Create a mail sender program MailServer mail = new MailServer (m); // send mail. Sendmail ();}}

The running result is as follows:

==== Email message being sent ====

Sender: a@a.com

Recipient: B @ B .com

Email title: aliens attacked the earth

Email content:

Content-Type: multipart/mixed; charset = gb2312

In the end, aliens were steushed by Chinese people!

The mail format is: hypertext format

Of course, if you want to generate an email in text format, you only need to slightly modify the scenario class: New htmlmail is changed to new textmail, which can be implemented by the reader on its own, which is very simple. In this scenario, we use the policy mode to implement free switching between the two algorithms. It provides the following guarantee: The two behaviors of encapsulated emails are optional, the upper-layer module determines which algorithm to choose. The task to be completed in Rule mode is to provide two alternative algorithms.

33.1.2 send emails in Bridge Mode

The Bridge pattern focuses on the separation of abstraction and implementation. It is a structural pattern that studies how to build a software architecture, let's take a look at how the Bridge Mode constructs a mail sending architecture, as shown in 3-3.

Figure 33-3 Send email in Bridge Mode

The Sendmail and Postfix email server implementation classes are added to the class diagram. The sender tag can be added to the mail template. The other settings are the same as those in the Policy mode. It is indeed very similar. Let's take a look at it. We have completed an independent architecture here, And the email sending server also has it. It is a complete mail sending program. It should be noted that the Sendmail class is not a verb action (send mail). It refers to an open-source mail server product. Generally, the default Mail Server of * nix system is sendmail; postfix is also an open-source mail server product. Its performance and stability are gradually surpassing Sendmail.

Let's take a look at the code implementation. The mail template only adds an add method, as shown in code listing 3-7.

Code List 33-6 email templates

Public abstract class mailtemplate {/** this part of the code remains unchanged. Refer to the code list 33-1. * /// Add public void add (string sendinfo) {context = sendinfo + context;} No changes have been made to text and hypertext emails, as shown in code listing 33-2 and 33-3, we will not go into details here. Let's take a look at the mail server, that is, the abstract role of the bridge mode, as shown in code listing 33-7. Code List 33-7 email server public abstract class MailServer {// which email was sent protected final mailtemplate m; Public MailServer (mailtemplate _ m) {This. M = _ m;} // send the public void Sendmail () {system. out. println ("==== mail message being sent ==="); // sender system. out. println ("Sender:" + M. getfrom (); // recipient system. out. println ("Recipient:" + M. getto (); // The title system. out. println ("mail title:" + M. getsubject (); // The email content system. out. println ("email content:" + M. getcontext ());}}

This class has two changes to the environment role of the Policy mode:

◇ Modify to abstract class

Why do I need to modify it to an abstract class? Because we are designing an architecture, do you think the mail server is a specific and instantiated object? Can "Give me an email server" be implemented? No, you can only say "give me a postfix mail service". This can be achieved only by providing a clear and traceable object.

◇ Variable M is changed to protected access permission to facilitate subclass calls

Now let's take a look at the implementation of the Postfix mail server, as shown in the code list 3-8.

Code List 33-8 Postfix email server

 
Public class Postfix extends MailServer {public Postfix (mailtemplate _ m) {super (_ m);} // fixed the mail sender program public void Sendmail () {// added the mail server information string context = "Received: From xxxx (unknown [xxx. xxx. xxx. xxx]) by aaa.aaa.com (postfix) with esmtp id 8dbcd172b8 \ n "; super. m. add (context); super. sendmail ();}}

Why do I need to overwrite the Sendmail program? It is because each mail server will leave its own mark on the mail content when sending the mail. One is the role of advertising, the other is to facilitate the Internet statistics, and the third is to facilitate the resonance of homogeneous software. Let's take a look at the implementation of Sendmail mail, as shown in the code list 3-9.

Code List 33-9 Sendmail mail server

 
Public class Sendmail extends MailServer {// pass a public Sendmail (mailtemplate _ m) {super (_ m) ;}// fixed the mail sender @ overridepublic void Sendmail () {// Add the email server information super. m. add ("Received: (Sendmail); 7 Nov 2009 04:14:44 + 0100"); super. sendmail ();}}

Both the email and email server are available. Let's see how to send the email, as shown in the code list 33-10.

Code List 33-10 scenario classes

Public class client {public static void main (string [] ARGs) {// create a text-format email mailtemplate M = new htmlmail ("a@a.com", "B @ B .com ", "aliens attacked the Earth", "the ending is that aliens were swallowed up by Chinese people! "); // Use Postfix to send mail MailServer mail = new Postfix (m); // send mail. Sendmail ();}}

The running result is as follows:

==== Email message being sent ====

Sender: a@a.com

Recipient: B @ B .com

Email title: aliens attacked the earth

Email content:

Content-Type: multipart/mixed; charset = gb2312

Received: From xxxx (unknown [XXX. XXX]) by aaa.aaa.com (postfix) with esmtp id 8dbcd172b8

In the end, aliens were steushed by Chinese people!

The mail format is: hypertext format

Of course, there are three other ways to send mail: Postfix to send text mail, Sendmail to send text mail and ultra text mail, the modification is very small, you can modify the implementation, reflecting the differences between the bridge mode.

33.1.3 Best Practices

The rule mode and the bridge mode are so similar that we can only analyze them from their intentions. The rule mode is an Action Mode Designed to encapsulate a series of behaviors, in this example, we think that it is an action to encapsulate the necessary information (sender, recipient, title, content) of an email into an object. The behavior varies depending on the Encapsulation Format (algorithm. The bridge mode is used to extract the abstract part and the implementation part without damaging the encapsulation. The premise is that the encapsulation is not damaged, let the abstract Part and implementation part change independently. In this example, can our mail server and mail template be changed independently? Whether it is a mail server or a mail template, as long as it inherits the abstract class, it can continue to expand, its main purpose is to build a scalable architecture without disrupting encapsulation.

In short, the policy mode uses inheritance and Polymorphism to establish a set of algorithms that can be freely switched, the bridge mode is a mode where abstraction and implementation can be independently extended without disrupting encapsulation.

It's hard to distinguish, right? Think about the intention of both of them to understand why we need to build two similar models. Do not think too much about the differences between them. It is the right way to use them. When designing a system, we may not consider whether it is a policy mode or a bridge mode, the problem can be solved. "No matter whether it's a black cat or a white cat, it's a good cat to catch a mouse ".

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.