13. Decorative mode

    There are too many decorative patterns used in China. The Chinese culture is the culture of the mean. You can't speak or do things too directly. You need to be skilled. You do this wrong, you do that wrong, you must first affirm his achievements, praise his strengths, then point out the flaws, point out the mistakes, and finally give an incentive, what are the benefits after you revise these shortcomings, such as you You can bring more soldiers, more small bosses, etc., otherwise you will be criticized as soon as you come up. If you look at it, you must be unconvinced, contradict or even directly "I don't leave the master here, I have the place to leave the master. "Walk away. This is talking, but there are also many things to do. Before the popularity of knockoff products, counterfeit goods were very popular. I bought a mobile phone in 2002. At that time, the boss made a lot of noise and promised that this mobile phone is the latest. Like, the case is brand new, the packaging is brand new, without any flaws, just a lot cheaper than the original, then I bought it, I was short of money, it took 3 months, it broke, and it was sent for repair and inspection, Saying this is a new case with an old machine, I'm dizzy! Take the circuit board of an old mobile phone, find a new shell and screen, and package it to become a new mobile phone. The decoration mode is very harmful!

    Let's not talk about unhappy things, what is an example today? Let's talk about the smell of my elementary school. When I was in elementary school, my academic performance was very poor. There were more than 40 students in the class, and I was basically ranked after 45. According to the definition given to me by the teacher, I was "not reading material", but my father was very strict. , I know that I don’t have this material, so I’m still rushing the ducks to the shelves. Every time I finish the exam, I’ll be fighting brilliantly. “Bamboo shoots fried meat” is definitely indispensable. After the final exam of the fourth grade, the school made a very bad trick (this trick is very popular now), print out the transcript, and ask the parents to sign, and then you can go to the fifth grade. My fear, but it only takes a few seconds. Time, play and forget everything.

    Let's look at the program:

content:


The abstract class of the transcript, and then there is a fourth-grade transcript implementation class, first look at the abstract class:

SchoolReport.java

package No13_DecoratorPattern;

public abstract class SchoolReport {

    //The main display of the transcript is your score
    public abstract void report();

    //The transcript must be signed by the parents, this is the most terrible
    public abstract void sign(String name);
}

Our implementation class FifthGradSchoolReport.java

package No13_DecoratorPattern;

public class FouthGradeSchoolReport extends SchoolReport {
    // my transcript
    @Override
    public void report() {
        //The format of the transcript is like this
        System.out.println("Dear XXX parents");
        System.out.println("......");
        System.out.println("Language 62 Math 65 Physical Education 98 Natural 63");
        System.out.println("......");
        System.out.println("Parent Signature");
    }

    //parent's signature
    @Override
    public void sign(String name) {
        System.out.println("Parent's signature: "+name);
    }
}

The transcripts are out. Don't look at grades like 62 and 65. You must know that if you score below 90 in elementary school, you are basically in the middle and lower classes. Hey, there are too many people who love learning! What's the matter, then I'll show this report card to Dad?

Dad began to look at the transcript. This transcript is the most real, nothing has been touched, original, look at the Father class:

Father.java

package No13_DecoratorPattern;

public class Father {
    public static void main(String[] args) {
        //Bring the transcript
        SchoolReport sr = new FouthGradeSchoolReport();

        // look at the transcript
        sr.report();

        //sign? Forget it!
    }
}

operation result;


Do you want me to sign this score? ! Dad started looking for a broom, my ass is ready, the muscles need to be tight, or it will hurt too much! Haha, fortunately, this was not the real situation at the time. I did not directly hand the transcript to my dad, but did some technical work before handing it over to him. I need to encapsulate the transcript. The encapsulation is done in two steps. :

    Step 1: Tell dad the highest score in each subject, the highest score in Chinese is 75, the highest in mathematics is 78, and naturally it is 80. Then dad thinks that my score is similar to the highest score. This is the truth, but I don’t know the reason. Anyway, the final exams are not very good, but they are basically concentrated on the score of 70 or more. My score of more than 60 is basically the bottom of the role:

    Part 2: After my dad looked at the report card, he told him that I was ranked 38th in the whole class. This is also true. Why? Nearly ten students dropped out! I'm not talking about this. I don’t know if it was the first time that the report card was issued. The school didn’t think about it clearly. It didn’t write how many students there were in total, how many students they ranked, etc. Anyway, I took advantage of it.

Now let's modify the program

By directly adding a subclass and overriding the report method, this problem is easily solved, isn't it? Yes, it is, it is indeed a good method, let's look at the specific implementation:

package No13_DecoratorPattern;

/**
 * Beautify this transcript
 * The word Sugar is so good, the noun means sugar and the verb is to beautify
 */
public class SugarFouthGradeSchoolReport extends FouthGradeSchoolReport {
    //First of all, you must define the method you want to beautify, first tell dad the highest grade in school
    private void reportHighScore(){
        System.out.println("The highest test language is 75, math is 78, naturally it is 80");
    }

    //After Dad reads the transcript, I will report the school's ranking
    private void reportSort(){
        System.out.println("I am number 38...");
    }

    //Because the reported content has changed, it is necessary to rewrite the parent class
    @Override
    public void report() {
        this.reportHighScore(); //First talk about the highest score
        super.report(); //Then dad looks at the transcript
        this.reportSort(); //Then tell dad to learn ranking
    }
}

Then the Father class is slightly modified to see the beautified transcript. The code is as follows:

package No13_DecoratorPattern;

public class Father {
    public static void main(String[] args) {
        //Bring the transcript
        SchoolReport sr = new SugarFouthGradeSchoolReport();

        // look at the transcript
        sr.report();

        //Then Dad saw it, was very happy, and signed it
        sr.sign("Zhang San");
    }
}

operation result:


    This problem can indeed be solved through inheritance. Dad was very happy when he saw the transcript, and then signed it, but the reality is very complicated. Maybe after listening to my report on the highest score, Dad would be happy and signed directly. Now, the following rankings are not necessary, or Dad needs to listen to the rankings first, then what should I do? Continue to extend the class? How many classes can you extend? This is still a relatively simple scenario. Once there are many conditions that need to be decorated, such as 20, you can solve it through inheritance. How many subclasses do you think? Are you about to collapse!

    Well, you can also see that there are indeed problems with inheritance, the explosion of classes, and the increase in the number of classes. It is strange that you are not exhausted by writing these classes, and you have to think about how to maintain them in the future. Who is willing to accept such a large number of classes Where is the maintenance? And in object-oriented design, if there are more than 2 levels of inheritance, you should think about whether there is a design problem, and whether you should find a new path. This is experience, not absolute, the more inheritance levels you have in the future. The more maintenance costs, the more problems, what should I do? Easy to handle, the decoration mode comes in to solve these problems.

Add an abstract class and two implementation classes. The role of Decorator is to encapsulate the SchoolReport class. See the source code:

content:


Decorator.java

package No13_DecoratorPattern;

public abstract class Decorator extends SchoolReport{
    //First I need to know which transcript it is
    private SchoolReport sr;

    //Constructor, pass the transcript over
    public Decorator(SchoolReport sr){
        this.sr = sr;
    }

    //The transcript is still to be seen
    public void report(){
        this.sr.report();
    }


    // After reading the transcript, you still need to sign
    public void sign(String name){
        this.sr.sign(name);
    }
}

The purpose of the Decorator abstract class is very simple, that is, to let subclasses encapsulate the subclasses of SchoolReport, how to encapsulate them? Rewrite the report method! First look at the HighScoreDecorator implementation class:

package No13_DecoratorPattern;

public class HighScoreDecorator extends Decorator {
    //Constructor
    public HighScoreDecorator(SchoolReport sr){
        super(sr);
    }

    //I want to report the highest score
    private void reportHighScore(){
        System.out.println("The highest test language is 75, math is 78, naturally it is 80");
    }

    //The highest grade I have to tell my dad before he sees the report card, otherwise he will pick up the broom and beat me when he sees it. How can I have the chance to say it?
    @Override
    public void report() {
        this.reportHighScore();
        super.report();
    }
}

Rewrite the report method, first call the decoration method reportHighScore of the specific decoration class, and then call the method of the specific component, let's look at how to report the sorting of the school SortDecorator code:

package No13_DecoratorPattern;

public class SortDecorator extends Decorator {
    //Constructor
    public SortDecorator(SchoolReport sr){
        super(sr);
    }

    //Tell dad the ranking of the school
    private void reportSort(){
        System.out.println("I am number 38...");
    }

    //Dad tell him after reading the transcript to strengthen the effect
    @Override
    public void report() {
        super.report();
        this.reportSort();
    }
}

Then look at how my dad looked at the transcript:

package No13_DecoratorPattern;

public class Father {
    public static void main(String[] args) {
      //Bring the transcript
        SchoolReport sr;
        sr = new FouthGradeSchoolReport(); //Original transcript

        //The transcript with the highest score description added
        sr = new HighScoreDecorator(sr);

        //Added a description of the score ranking
        sr = new SortDecorator(sr);

        // look at the transcript
        sr.report();

        //Then Dad, when he saw it, he was very happy and signed it.
        sr.sign("old third");
    }
}

operation result:



Dad looked at the report card and listened to me. He was very happy. His son has made progress. He has improved from more than 40 to more than 30. He has made great progress and escaped a bad meal.

This is the decoration mode. The general class diagram of the decoration mode is as follows:


    Looking at the class diagram, Component is an interface or an abstract class, which defines our core object, that is, the most primitive object, such as the transcript above, remember that in the decoration mode, there must be one extracted from the most core, The most primitive and basic interface or abstract class is Component.

    ConcreteComponent is the implementation of the most core, primitive, and most basic interface or abstract class. What you want to decorate is this stuff.

    Decorator is generally an abstract class, what is it used for? To implement an interface or abstract method, it may not necessarily have an abstract method in it. There must be a private variable in its properties pointing to the Component.

    ConcreteDecoratorA and ConcreteDecoratorB are two specific decoration classes. You need to decorate your most core, primitive, and basic things. The above example is to decorate a relatively mediocre transcript into a parent-approved transcript. .

    The decoration pattern is a powerful complement to inheritance. You must know that inheritance is not a panacea. Inheritance can solve practical problems, but in the project you have to consider many things such as easy maintenance, easy extension, easy reuse, etc., and in some cases (For example, the transcript example above) If you use inheritance, you will add a lot of subclasses, and the flexibility is very poor. Of course, maintenance is not easy. That is to say, the decoration mode can replace inheritance and solve the problem of our class expansion. You need to know that inheritance adds functions to classes statically, while decoration mode adds functions dynamically. Look at the example above. I don't want the encapsulation of SortDecorator. It's very simple. Just remove it from Father. Well, if you use inheritance you have to modify the program.

    The decoration mode also has a very good advantage, the scalability is very good. In a project, you will have a lot of factors that you cannot take into account, especially business changes, and a requirement will pop up from time to time, especially when a project is proposed. When there is a lot of delayed demand, the mood is..., I really want to scold my mother. The decoration pattern can help us very well. Re-encapsulate a class through the decoration pattern, instead of doing it through inheritance. To put it simply, there are three inheritance relationships, Father, Son, and GrandSon. I want to enhance the Son class. What about functions? I think you will resolutely push back! Not allowed, by the way, why? Are your enhancements modifying the methods in the Son class? Add method? Impact on GrandSon that? Especially when there are multiple GrandSons, what do you do? The workload of this evaluation is enough for you, so this is not allowed, and the problem still needs to be solved. What should I do? Modifying Son by establishing the SonDecorator class is equivalent to creating a new class, which does not change the original program, and the change is well completed through expansion.




The content comes from "Introduction to 24 Design Patterns and 6 Design Principles"



















Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324692013&siteId=291194637