The template method in the design mode is used in the Ruby application instance, and the ruby application instance.

Source: Internet
Author: User

The template method in the design mode is used in the Ruby application instance, and the ruby application instance.

Instance 1
Today, you have started programming as usual.
The project manager tells you that you want to add a new function on the server today. You want to write a method to process the Book object and wrap all the fields of the Book object in XML format, in this way, you can easily interact with the client. In addition, logs must be printed before and after the packaging starts to facilitate debugging and problem locating.
No problem! You think this feature is just a piece of cake, and you are very confident to start writing code.
The code of the Book object is as follows:

class Book  attr_accessor :book_name, :pages, :price, :author, :isbn end 

Then write a class specifically used to wrap the Book object into XML format:

class Formatter   def format_book(book)   puts "format begins"   result = "<book_name>#{book.book_name}</book_name>\n"   result += "<pages>#{book.pages}</pages>\n"   result += "<price>#{book.price}</price>\n"   result += "<author>#{book.author}</author>\n"   result += "<isbn>#{book.isbn}</isbn>\n"   puts "format finished"   result  end  end 

 
The call code is as follows:

book = Book.new book.book_name = "Programming Ruby" book.pages = 830 book.price = 45 book.author = "Dave Thomas" book.isbn = "9787121038150" formatter = Formatter.new result = formatter.format_book(book) puts result 

After you write it, you can't wait to start running, and the running results fully meet your expectations.

After reading this, the project manager is very satisfied with you. The efficiency is very high! You are also very proud.
However, two days later, the project manager found you again. He said that he did not consider the clients that needed to interact, including mobile phone devices, and mobile phone devices both ate traffic, it is too traffic-consuming to transmit data in XML format. It is recommended that the data be transmitted in JSON format. However, the previous XML format should also be retained. It is best to specify the format used by the client.
You are a little unhappy and have an underestimating mind. Why didn't you think about it at first? Now you have to change the legacy code. After all, the other party is the leader, and you still have to obey the command, so you begin to modify the Formatter class:

class Formatter   def format_book(book, format)   puts "format begins"   result = ""   if format == :xml    result += "<book_name>#{book.book_name}</book_name>\n"    result += "<pages>#{book.pages}</pages>\n"    result += "<price>#{book.price}</price>\n"    result += "<author>#{book.author}</author>\n"    result += "<isbn>#{book.isbn}</isbn>\n"   elsif format == :json    result += "{\n"    result += "\"book_name\" : \"#{book.book_name}\",\n"    result += "\"pages\" : \"#{book.pages}\",\n"    result += "\"price\" : \"#{book.price}\",\n"    result += "\"author\" : \"#{book.author}\",\n"    result += "\"isbn\" : \"#{book.isbn}\",\n"    result += '}'   end   puts "format finished"   result  end  end 

The call code is as follows:

book = Book.new book.book_name = "Programming Ruby" book.pages = 830 book.price = 45 book.author = "Dave Thomas" book.isbn = "9787121038150" formatter = Formatter.new result = formatter.format_book(book, :xml) puts result result = formatter.format_book(book, :json) puts result 

Run the program again and get the following results.

After seeing the running result, the Project Manager happily said, "Great, this is exactly what I want !"
However, you are not so happy this time. You think the code is a bit messy. The logic in XML format is mixed with the logic in JSON format, which is very difficult to read, in addition, it will be very difficult to extend functions in the future. Fortunately, the transmission format is generally XML and JSON, and there should be no extensions, so you can comfort yourself.
However, fantasies will always be broken by reality. "I recently heard that a YAML format is fun..." said the project manager. At this time, you have an impulse to beat people !!!

Most of the time, the code written in the company is messy and of poor quality. A major reason is that the demand changes. We constantly add various subsequent additions based on the original code. Our code becomes unsightly under the if statement added in a row. Of course, as a programmer, we do not have much right to speak about such things as demand, and we can't do anything about it. However, we can design the program architecture as much as possible, so that the code we write is more scalable, so that we can respond to various changes in requirements.

Below you will use the template method in 23 design patterns to improve the above program.
First, define a special subclass to process the specific logic of each transmission format, so that the logic of different transmission formats can be separated from one method, which is obviously easy to read and understand.
The definition class XMLFormatter inherits from Formatter, which includes the specific logic for processing the XML format:

class XMLFormatter < Formatter   def formating(book)   result = "<book_name>#{book.book_name}</book_name>\n"   result += "<pages>#{book.pages}</pages>\n"   result += "<price>#{book.price}</price>\n"   result += "<author>#{book.author}</author>\n"   result += "<isbn>#{book.isbn}</isbn>\n"  end  end 

The definition class JSONFormatter inherits from the Formatter, which includes the specific logic for processing the JSON format:

class JSONFormatter < Formatter    def formating(book)   result = "{\n"   result += "\"book_name\" : \"#{book.book_name}\",\n"   result += "\"pages\" : \"#{book.pages}\",\n"   result += "\"price\" : \"#{book.price}\",\n"   result += "\"author\" : \"#{book.author}\",\n"   result += "\"isbn\" : \"#{book.isbn}\",\n"   result += '}'  end   end 

Modify the code in Formatter as follows:

class Formatter   def format_book(book)   before_format   result = formating(book)   after_format   result  end    def before_format   puts "format begins"  end    def formating(book)   raise "You should override this method in subclass."  end    def after_format   puts "format finished"  end  end 

You will find that the format_book method has only four steps. The first step is to call before_format to print the logs before the format conversion. The second step is to call formating to process the specific conversion logic. However, The formating method only has an exception in raise, because the specific conversion logic should be processed by sub-classes, if the formating method of the parent class is used, an exception occurs. Step 3 call after_format to print the log after the format conversion. Step 4: return the result.
The call code is as follows:

book = Book.new book.book_name = "Programming Ruby" book.pages = 830 book.price = 45 book.author = "Dave Thomas" book.isbn = "9787121038150" xmlFormatter = XMLFormatter.new result = xmlFormatter.format_book(book) puts result jsonFormatter = JSONFormatter.new result = jsonFormatter.format_book(book) puts result 

After running, you will find that the running results are exactly the same as those of the code before modification. However, after the template method is used, the code readability is greatly improved, because the code for processing format conversion is put into their respective classes, rather than all being inserted into one method. In addition, the scalability has also been greatly improved. For example, you are interested in the YAML format described by the Project Manager.
The definition class YAMLFormatter inherits from the Formatter, which includes the specific logic for processing the YAML format:

class YAMLFormatter < Formatter   def formating(book)   result = "book_name: #{book.book_name}\n"   result += "pages: #{book.pages}\n"   result += "price: #{book.price}\n"   result += "author: #{book.author}\n"   result += "isbn: #{book.isbn}\n"  end  end 

To call the code, you only need to add:

yamlFormatter = YAMLFormatter.new result = yamlFormatter.format_book(book) puts result 

Well, the annoying YAML format is supported in this way. You only need to decide whether to instantiate XMLFormatter, JSONFormatter or YAMLFormatter during the call, and then convert the format according to the corresponding specifications. The overall code is very organized and looks comfortable. At this time, you will easily ridicule the Project Manager, do you still need to support the format?

Instance 2

Requirements:

Students copy questions and make questions

Initial code

#-*-Encoding, the Xuan iron of Tu longdao may be []. ductile Iron B. tinplate c. high-speed alloy steel d. carbon-Plastic Fiber 'put' answer: B 'end def question2 puts' Yang Guo, Cheng Ying, Lu wushuang wiped out the love flower, resulting in []. make this plant no longer harm B. extinction of a rare species c. destroying the ecological balance of the biosphere d. result In desertification in the region. Answer: a 'end def question3 puts 'The Blue Phoenix results in the vomiting of Huashan shitu and taogu Liuxian. If you are a doctor, what medicine will they take? []. aspirin B. niuhuang Jiedu tablets c. mongod. let them drink a lot of raw milk e. none of the above is true. Answer: c 'endend # student B's exam class TestPaperB def question1 puts 'Yang once got it. Later, Guo Jing was given the result of computation to Yi tianjian, the Xuan iron of Tu longdao may be []. ductile Iron B. tinplate c. high-speed alloy steel d. carbon-Plastic Fiber 'put' answer: d' end def question2 puts 'Yang Guo, Cheng Ying, Lu wushuang eradicate the love flower, resulting in []. make this plant no longer harm B. extinction of a rare species c. destroying the ecological balance of the biosphere d. resulting in desertification in the region 'puts' answer: B 'end def question3 puts' The Blue Phoenix results in the vomiting of Huashan shitu and taogu Liuxian. If you are a doctor, what medicine will they take? []. aspirin B. niuhuang Jiedu tablets c. mongod. let them drink a lot of raw milk e. none of the above are correct. Answer: a 'endendputs' students copied by students 'student1 = TestPaperA. newstudent1.question1student1. question2student1. question3puts 'student2 = TestPaperB. newstudent2.question1student2. question2student2. question3

Problems:

The code in TestPaperA and TestPaperB is much the same, which is not conducive to maintenance. If you need to modify the question, you need to modify the two parts.
Modified code

#-*-Encoding: UTF-8-*-class TestPaper def question1 puts. Later, Guo Jing was given to compress, which may be. ductile Iron B. tinplate c. high-speed alloy steel d. carbon-Plastic Fiber 'end def question2 puts 'Yang Guo, Cheng Ying, and Lu wushuang have eliminated the love flower, resulting in []. make this plant no longer harm B. extinction of a rare species c. destroying the ecological balance of the biosphere d. the 'end def question3 puts 'Blue Phoenix in the region caused the Huashan shitu and taogu Liuxian to vomit. If you are a doctor, what medicine will you give them? []. aspirin B. niuhuang Jiedu tablets c. mongod. let them drink a lot of raw milk e. none of the above are 'endend # student a's exam class TestPaperA <TestPaper def question1 super puts' answer: B 'end def question2 super puts' answer: a 'end def question3 super puts' answer: C' endend # student B's exam class TestPaperB <TestPaper def question1 super puuts 'Answer: d' end def question2 super puuts' answer: B 'end def question3 super puuts' Answer: a' endendpuuts 'Students' student1 = TestPaperA. newstudent1.question1student1. question2student1. question3puts 'student2 = TestPaperB. newstudent2.question1student2. question2student2. question3

It can be seen that a public examination paper is extracted to allow a and B to inherit and share the questions. Now let's look at TestPaperA and TestPaperB. The only difference is that answers a, B, c, and d are different, and others are the same.

#-*-Encoding: UTF-8-*-class TestPaper def question1 puts. Later, Guo Jing was given to compress, which may be. ductile Iron B. tinplate c. high-speed alloy steel d. carbon-Plastic Fiber 'puts "Answer: # {answer1}" end def question2 puts 'Yang Guo, Cheng Ying, Lu wushuang wiped out the flowers, resulting in []. make this plant no longer harm B. extinction of a rare species c. destroying the ecological balance of the biosphere d. cause desertification in the region 'puts "Answer: # {answer2}" end def question3 puts 'Blue Phoenix causes vomiting of Huashan shitu and taogu Liuxian. If you are a doctor, what medicine will they take? []. aspirin B. niuhuang Jiedu tablets c. mongod. let them drink a lot of raw milk e. none of the above is correct. Answer: # {answer3} "end def answer1; end def answer2; end def answer3; endend # student a's exam class TestPaperA <TestPaper def answer1 'B' end def answer2 'A' end def answer3 'C' endend # student B's exam class TestPaperB <TestPaper def answer1 'D' end def answer2 'B' end def answer3 'A' endendputs 'student1 = TestPaperA. newstudent1.question1student1. question2student1. question3puts 'student2 = TestPaperB. newstudent2.question1student2. question2student2. question3

Here, the answers in TestPaperA and TestPaperB are extracted from the parent class and only different parts are saved.

When the parent class becomes a subclass template, all repeated code should be raised to the parent class, instead of making every subclass repeat.

When we want to complete a process or a series of steps at a specific level of detail, but the implementation of individual steps at a more detailed level may be different, we usually consider using the template method mode for processing.

Articles you may be interested in:
  • Detailed description of the structure of the Combination Mode and Its Application in Ruby Design Mode Programming
  • Example parsing: Use of Strategy Mode in Ruby Design Mode Programming
  • The example explains how Ruby uses the decorator mode in the design mode.
  • Example of using Builder mode in Ruby Design Mode Programming
  • Detailed description of the Application of Singleton mode in Ruby Design Mode Programming
  • Programming in Ruby design mode-Introduction to adapter Mode
  • Ruby uses code instances in the proxy mode and decoration mode in the Design Mode
  • Ruby uses the simple factory mode and factory method mode in the Design Mode
  • Application instance analysis of appearance mode in Ruby Design Mode Programming

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.