Reprinted please indicate the source: http://blog.csdn.net/guolin_blog/article/details/8744002
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:
public class Book {private String bookName;private int pages;private double price;private String author;private String isbn;public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public int getPages() {return pages;}public void setPages(int pages) {this.pages = pages;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getIsbn() {return isbn;}public void setIsbn(String isbn) {this.isbn = isbn;}}
Then write a class specifically used to wrap the book object into XML format:
public class Formatter {public String formatBook(Book book) {System.out.println("format begins");String result = "";result += "<book_name>" + book.getBookName() + "</book_name>\n";result += "<pages>" + book.getPages() + "</pages>\n";result += "<price>" + book.getPrice() + "</price>\n";result += "<author>" + book.getAuthor() + "</author>\n";result += "<isbn>" + book.getIsbn() + "</isbn>\n";System.out.println("format finished");return result;}}
The call code is as follows:
public class Test {public static void main(String[] args) throws Exception {Book book = new Book();book.setBookName("Thinking in Java");book.setPages(880);book.setPrice(68);book.setAuthor("Bruce Eckel");book.setIsbn("9787111213826");Formatter formatter = new Formatter();String result = formatter.formatBook(book);System.out.println(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:
public class Formatter {public static final int XML = 0;public static final int JSON = 1;public String formatBook(Book book, int format) {System.out.println("format begins");String result = "";if (format == XML) {result += "<book_name>" + book.getBookName() + "</book_name>\n";result += "<pages>" + book.getPages() + "</pages>\n";result += "<price>" + book.getPrice() + "</price>\n";result += "<author>" + book.getAuthor() + "</author>\n";result += "<isbn>" + book.getIsbn() + "</isbn>\n";} else if (format == JSON) {result += "{\n";result += "\"book_name\" : \"" + book.getBookName() + "\",\n";result += "\"pages\" : \"" + book.getPages() + "\",\n";result += "\"price\" : \"" + book.getPrice() + "\",\n";result += "\"author\" : \"" + book.getAuthor() + "\",\n";result += "\"isbn\" : \"" + book.getIsbn() + "\",\n";result += "}";}System.out.println("format finished");return result;}}
The call code is as follows:
public class Test {public static void main(String[] args) throws Exception {Book book = new Book();book.setBookName("Thinking in Java");book.setPages(880);book.setPrice(68);book.setAuthor("Bruce Eckel");book.setIsbn("9787111213826");Formatter formatter = new Formatter();String result = formatter.formatBook(book, Formatter.XML);System.out.println(result);result = formatter.formatBook(book, Formatter.JSON);System.out.println(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, modify the code in formatter as follows:
public abstract class Formatter {public String formatBook(Book book, int format) {beforeFormat();String result = formating(book);afterFormat();return result;}protected void beforeFormat() {System.out.println("format begins");}protected abstract String formating(Book book);protected void afterFormat() {System.out.println("format finished");}}
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 calls formating. This method is an abstract method used to process specific conversion logic. Therefore, every subclass inherited from formatter needs to override this method to implement its own conversion logic. Step 3 call after_format to print the log after the format conversion. Step 4: return the result. Since there are abstract methods in the class, we need to declare the formatter as an abstract class.
Then 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 easier to read and understand.
The definition class xmlformatter inherits from formatter, which includes the specific logic for processing the XML format:
public class XMLFormatter extends Formatter {@Overrideprotected String formating(Book book) {String result = "";result += "<book_name>" + book.getBookName() + "</book_name>\n";result += "<pages>" + book.getPages() + "</pages>\n";result += "<price>" + book.getPrice() + "</price>\n";result += "<author>" + book.getAuthor() + "</author>\n";result += "<isbn>" + book.getIsbn() + "</isbn>\n";return result;}}
The definition class jsonformatter inherits from the formatter, which includes the specific logic for processing the JSON format:
public class JSONFormatter extends Formatter {@Overrideprotected String formating(Book book) {String result = "";result += "{\n";result += "\"book_name\" : \"" + book.getBookName() + "\",\n";result += "\"pages\" : \"" + book.getPages() + "\",\n";result += "\"price\" : \"" + book.getPrice() + "\",\n";result += "\"author\" : \"" + book.getAuthor() + "\",\n";result += "\"isbn\" : \"" + book.getIsbn() + "\",\n";result += "}";return result;}}
The call code is as follows:
public class Test {public static void main(String[] args) throws Exception {Book book = new Book();book.setBookName("Thinking in Java");book.setPages(880);book.setPrice(68);book.setAuthor("Bruce Eckel");book.setIsbn("9787111213826");XMLFormatter xmlFormatter = new XMLFormatter();String result = xmlFormatter.formatBook(book);System.out.println(result);JSONFormatter jsonFormatter = new JSONFormatter();result = jsonFormatter.formatBook(book);System.out.println(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:
public class YAMLFormatter extends Formatter {@Overrideprotected String formating(Book book) {String result = "";result += "book_name: " + book.getBookName() + "\n";result += "pages: " + book.getPages() + "\n";result += "price: " + book.getPrice() + "\n";result += "author: " + book.getAuthor() + "\n";result += "isbn: " + book.getIsbn() + "\n";return result;}}
To call the code, you only need to add:
YAMLFormatter yamlFormatter = new YAMLFormatter();String result = yamlFormatter.formatBook(book);System.out.println(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?
Template Method: defines the skeleton of an algorithm in an operation, and delays some steps to the subclass, the template method allows the subclass to redefine certain steps of an algorithm without changing the structure of an algorithm.