Application of template method pattern in design pattern in Ruby two _ruby topics

Source: Internet
Author: User

Instance One
today you come to work as usual and start your programming work as always.
The project manager tells you that today you want to add a new feature to the server, and you want to write a method that handles the book object, wrapping all the fields of the book object in XML format so that you can easily interact with the client later. and print the log before and after the start of the package so that it is convenient to debug and problem-Orient.
No problem! You think this function is a piece of cake, very confidently began to write code.
The book object code is as follows:

Class book 
 Attr_accessor:book_name,:p ages,:p Rice,: Author, ISBN end 
 

Then write a class that is designed to wrap the book object in 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" 
  
 


The calling code is as follows:

Book = book.new 
book.book_name = "Programming Ruby" 
book.pages = 830 Book.price = \ book.author = 
"Dave T Homas " 
book.isbn =" 9787121038150 " 
formatter = formatter.new result 
= Formatter.format_book (book) 
Puts result 

After you've written it, you can't wait to start running and the results are exactly what you expected.

The project manager after reading, is very satisfied with you, the boy efficiency is very high! You are also very proud.
However, two days later, the project manager found you, he said before the need to consider the interaction of the client also includes mobile devices, and mobile devices are compared to eat traffic, in XML format to transmit too much traffic, think the best to change to use the JSON format transmission. However, the previous XML format should also be preserved, preferably by the client specifying which format to use.
You are a little unhappy, in the mind underestimate, why not at the beginning of the comprehensive, and now to change the legacy code. But the other party is the leader, you still have to obey the order, so you start 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 
 
 

The calling code is as follows:

Book = book.new 
book.book_name = "Programming Ruby" 
book.pages = 830 Book.price = \ book.author = 
"Dave T Homas " 
book.isbn =" 9787121038150 " 
formatter = formatter.new result 
= Formatter.format_book (book,: XML) 
puts result 
= Formatter.format_book (book,: JSON) 
puts result 

Run the program again and get the following results.

When the project manager sees the results, he says happily: "That's great, that's what I want!" ”
But you are not so happy this time, you think the code is a bit confusing, XML format logic and JSON format logic together, very bad for reading, and if you need to extend the functionality will be very difficult. Fortunately, the transfer format is also XML and JSON, there should be no extension, you can comfort yourself.
But fantasy will always be broken by reality, "I recently heard that there is a Yaml format is very fun ..." said the project manager. This time you've got the urge to hit someone,!!!.

Most of the time, the code written in the company is messy, the quality is very poor, a large part of the reason is because of the change in demand. We continue to supplement the various subsequent additions based on the original code, and our code becomes unsightly under the new if statement line. Of course, as programmers, we don't have much of a say in demand, and there's nothing we can do about it. But we can do our best to design the architecture of the program, let us write the code more extensibility, so that we can deal with a variety of requirements changes.

Below you will use the template method in 23 design patterns to improve the above program.
The first step is to define the specific subclass to handle each transmission format, so that the logic of the 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 adds specific logic to handle XML formats:

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" 
 
 

The definition class Jsonformatter inherits from formatter, which adds specific logic to handle 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 
  
 

The code in formatter is then modified as follows:

Class Formatter 
 
 def format_book (book) 
  before_format result 
  = formating (book) 
  After_format 
  result 
  
 -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 
 
 

You will find that the Format_book method is only four steps, and the first step is to call Before_format to print the log before the format conversion. The second step calls formating to handle the specific conversion logic, but the Formating method only raise an exception, because the logic of the specific transformation should be handled by subclasses, and if you go to the formating method of the parent class, you should see an exception. The third step calls After_format to print the converted log of the format. Step fourth returns result.
The final calling code is as follows:

Book = book.new 
book.book_name = "Programming Ruby" 
book.pages = 830 Book.price = \ book.author = 
"Dave T Homas " 
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 results of the run are identical to the results of the code before the modification. But after using the template method, the readability of the code has been greatly improved because the code that handles the format conversion is placed in its own class, rather than all of it in one method. And there has been a great increase in scalability, for example, you start to be interested in the YAML format that the project manager says.
The definition class Yamlformatter inherits from formatter, which adds specific logic to handle 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 
 
 

The calling code only needs to join:

Yamlformatter = yamlformatter.new Result 
= Yamlformatter.format_book (book) 
puts result 

Well, the headaches of the YAML format is supported, only to decide when the call is instantiated xmlformatter,jsonformatter or Yamlformatter, you can follow the corresponding specifications for format conversion. And the overall code is very organized and looks very comfortable. At this time, you will easily to the project manager to ridicule a sentence, there is a need to support the format?

Example Two

Demand:

Students copy the topic, do the topic

Initial code

#-*-Encoding:utf-8-*-#学生甲的试卷类 class Testpapera def Question1 puts ' Yang passed, and later gave Guo Jing, smelting into the Sky Sword, Dragon Sword of the Xuan Iron may be [] a. Ductile iron B. tinplate C. High-speed alloy steel d. Carbon-plastic fiber ' puts ' answer: B ' End def Question2 puts ' Yang, Chengying, Lu Wu-Wu to eradicate the love flower, resulting in [] a. Make this plant harmless. B. Destroy the ecological balance of the biosphere. D. The answer to the "puts" of desertification in the area: A ' end def Question3 puts ' Blue Phoenix's cause Huashan Apprentice, Peach Valley six cents vomit more than, if you are a doctor, will give them prescribe what medicine [] A. Aspirin B-Bezoar jiedu tablets C. Fluoride d. Make them drink big. Quantity of raw milk e. Above all wrong ' puts ' answer: C ' End #学生乙的试卷类 class Testpaperb def Question1 puts ' Yang passed, and later gave the Guo Jing, refining into a day sword, Dragon Sword of the Xuan Iron may be [] a. Ductile Iron B. tinplate c. High-speed alloy steel D. Carbon fiber ' puts ' answer: d ' End def Question2 puts ' Yang, Chengying, Lu Wu-Wu to eradicate the love flower, resulting in [] a. Make this plant harmless B. Make a rare species extinct C. destroyed the The ecological balance of the biosphere D. Causing desertification in the area ' puts ' answer: B ' End def Question3 puts ' Blue Phoenix's cause Huashan Apprentice, Peach Valley six cents vomit more than, if you are a doctor, will give them to prescribe what medicine [] A. Aspirin B-Bezoar jiedu tablets C . Fluorine acid D. Let them drink a lot of raw milk e. Above all wrong ' puts ' answer: A ' end end puts ' student a copy of the paper ' Student1 = testpapera.new student1.question1 student1.que
Stion2 Student1.question3 puts ' student b copy of the paper ' Student2 = testpaperb.new student2.question1 student2.question2

 Student2.question3

The problems that exist:

Testpapera and Testpaperb code in many of the same place, is not conducive to maintenance, if you need to modify the subject, it is necessary to change two places
The code after the change

 #-*-Encoding:utf-8-*-class Testpaper def Question1 puts ' Yang got it, and later gave it to Guo Jing, the Sword of Heaven, and the Dragon Slayer. The Xuan iron may be [] a. Ductile iron B. tinplate c. High-speed alloy steel d. Carbon-plastic fiber ' end def Question2 puts ' Yang, Chengying, Lu Wu-Wu to eradicate the love flower, resulting in [] a. Make this plant harmless B. To destroy a rare species. C. destroyed the creature. The ecological balance of the circle D. resulting in desertification in the region ' end def Question3 puts ' Blue Phoenix's cause Huashan master and apprentice, Peach Valley six cents vomit more than, if you are a doctor, will prescribe to them what medicine [] A. Aspirin B-Bezoar jiedu tablets C. Fluoride d. Let them drink a lot of raw milk E
  . None of the above is all right ' end #学生甲的试卷类 class Testpapera < Testpaper def Question1 Super puts ' answer: B ' End def Question2 Super puts ' answer: A ' End def Question3 Super puts ' answer: C ' End #学生乙的试卷类 class Testpaperb < Testpaper def Question1 Super puts ' answer: d ' End def Question2 Super puts ' answer: B ' End def Question3 Super puts ' answer: a ' E
nd end puts ' student a copy of the paper ' Student1 = testpapera.new student1.question1 student1.question2 student1.question3 ' student b copy of the paper ' Student2 = testpaperb.new student2.question1 student2.question2 student2.question3 

The

can be seen, extracted out of a public test class, let a B to inherit, the common one of the questions. Then look at Testpapera and Testpaperb, the difference is only the answer a, B, C, D is not the same, the others are the same.

 #-*-Encoding:utf-8-*-class Testpaper def Question1 puts ' Yang got it, and later gave it to Guo Jing, the Sword of Heaven, and the Dragon Slayer. The Xuan iron may be [] a. Ductile iron B. tinplate c. High-speed alloy steel D. Carbon fiber ' puts ' answer: #{answer1} "end def Question2 puts ' Yang, Chengying, Lu Wu-Wu to eradicate the love flower, resulting in [] a. Make this plant no longer harmful Man B. The extinction of a rare species C. Destroys the ecological balance of that biosphere. D. Causing desertification in the area ' puts ' answer: #{answer2} "end def Question3 puts ' Blue Phoenix's cause Huashan master and apprentice, Peach Valley six cents vomit more than, if you are a doctor , what drugs would they prescribe [] a. Aspirin B-Bezoar jiedu tablets C. Fluoride d. Let them drink a lot of raw milk e. The above all is not ' puts ' answer: #{answer3} "End Def Answer1; End Def Answer2; End Def Answer3; 
 End #学生甲的试卷类 Class Testpapera < Testpaper def Answer1 ' B ' End def Answer2 ' A ' "End def Answer3 ' C ' End #学生乙的试卷类 Class Testpaperb < Testpaper def Answer1 ' d ' End def Answer2 ' B ' End def Answer3 ' A ' end puts ' student a copy of the paper ' Student1 = testpapera.new student1.question1 student1.question2 student1.question3 ' student B copy Quiz paper ' Student2 = testpaperb.new student2.question1 student2.question2 student2.question3 

Here, the answers in Testpapera and Testpaperb are drawn from the parent class to save only the different parts.

The parent class becomes the template for the subclass, and all duplicated code should go up to the parent class instead of having to repeat each subclass.

When we want to complete a process or a series of steps that are consistent at a level of detail, but the implementation of individual steps at a more detailed level may not be the same, we usually consider using template method patterns for processing.

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.