当前位置:网站首页>[design pattern] Chapter 4: Builder mode is not so difficult

[design pattern] Chapter 4: Builder mode is not so difficult

2020-11-09 10:49:00 BWH_Steven

One introduction

explain : If you want to read the definition and other theoretical content directly , You can jump directly to the second largest point

There are a lot of scenes in life that we are going to talk about today “ Builder pattern ” It's a perfect match , For example, a computer is made up of CPU、 Memory 、 The graphics card 、 Memory 、 mouse 、 keyboard 、 Display and so on , We want a computer , We won't be able to make these accessories ourselves , It's usually done by telling the sales company , Then it sends production technicians to do the specified accessories for you .

I don't care , Who will buy it , Who does it , Who manages the problem , We can analyze and get , The one that builds computers “ The process ” It is stable. in other words , Whatever the configuration of the computer , These accessories are necessary , It's just The details are different , For example, your configuration is better , He's less than

however , I'm a buyer , I don't want to worry about that , I'll just tell you , I want a computer with medium configuration , You are responsible for “ build ” OK, just give it to me , This is the more popular way of saying the builder model

Here's an example of this computer , Take a look at it step by step :

Two Step by step through examples to understand the builder model

First , No matter how you build it , How to buy , One Computer Computer is a must , Let's randomly select three components to demonstrate ,CPU、 Memory 、 Monitor , To supplement get set toString Method

/**
 *  product : The computer 
 */
public class Computer {
    private String cpu; // CPU
    private String graphicsCard; //  Memory 
    private String displayScreen; //  Monitor 

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public String getGraphicsCard() {
        return graphicsCard;
    }

    public void setGraphicsCard(String graphicsCard) {
        this.graphicsCard = graphicsCard;
    }

    public String getDisplayScreen() {
        return displayScreen;
    }

    public void setDisplayScreen(String displayScreen) {
        this.displayScreen = displayScreen;
    }
    
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", graphicsCard='" + graphicsCard + '\'' +
                ", displayScreen='" + displayScreen + '\'' +
                '}';
    }
}

( One ) The simplest and most straightforward way ( Not good. )

This method basically has no technical content , direct new + set That's it

public class Test {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.setCpu(" Intel core  i5  processor ");
        computer.setGraphicsCard("4g Memory ");
        computer.setDisplayScreen("14 "  1080p 60hz Monitor ");
        System.out.println(computer.toString());
    }
}

Print the results :

Computer{cpu=' Intel core i5 processor ', graphicsCard='4g', displayScreen='14 " 1080p 60hz Monitor '}

( Two ) Customers contact production technicians directly

This way up here , Needless to say, it's not appropriate , So the technicians ( builder ) Here he comes ! But different technicians will make different accessories , For example, some can do 144hz Display for , And some specialize in 60hz Display for , There are high and low configuration , Different models

So we abstracted a ComputerBuilder The abstract class of

/**
 *  The computer builder 
 */
public abstract class ComputerBuilder {
    abstract void buildCpu(); //  build CPU
    abstract void buildGraphicsCard(); //  Building memory 
    abstract void buildDisplayScreen(); //  Building displays 

    abstract Computer getComputer(); //  Get this computer 
}

Let's write about the specific builder , For example, first write an implementation of a low configuration computer

/**
 *  Low configuration computer 
 */
public class LowConfigurationComputerBuilder extends ComputerBuilder {

    private Computer computer;

    public LowConfigurationComputerBuilder(){
        computer = new Computer();
    }

    @Override
    void buildCpu() {
        computer.setCpu(" Intel core  i5  processor ");
        System.out.println("buildCpu:  Intel core  i5  processor ");
    }

    @Override
    void buildGraphicsCard() {
        computer.setGraphicsCard("8g Memory ");
        System.out.println("buildGraphicsCard: 8g Memory ");
    }

    @Override
    void buildDisplayScreen() {
        computer.setDisplayScreen("1080p 60hz Monitor ");
        System.out.println("buildDisplayScreen: 1080p 60hz Monitor ");
    }

    @Override
    Computer getComputer() {
        return computer;
    }
}

Test it :

public class Test {
    public static void main(String[] args) {
        //  Create a low configuration computer builder 
        LowConfigurationComputerBuilder builder = new LowConfigurationComputerBuilder();
        builder.buildCpu();
        builder.buildGraphicsCard();
        builder.buildDisplayScreen();
        Computer computer = builder.getComputer();
        System.out.println(" Computers built : " + computer );
    }
}

Execution results :

buildCpu: Intel core i5 processor
buildGraphicsCard: 8g Memory
buildDisplayScreen: 1080p 60hz Monitor
Computers built : Computer{cpu=' Intel core i5 processor ', graphicsCard='8g Memory ', displayScreen='1080p 60hz Monitor '}

( 3、 ... and ) Customers contact the sales company

Although the above method is better than the first one , But the customer goes to contact the production technician himself , Obviously not very reasonable , Normal practice , We all contact the sales company first , Just tell them what configuration I want , I don't care about the details

public class SalesCompany {
    public Computer buildComputer(ComputerBuilder builder){
        builder.buildCpu();
        builder.buildGraphicsCard();
        builder.buildDisplayScreen();
        return builder.getComputer();
    }
}

Test code

public class Test {
    public static void main(String[] args) {
        //  Create a low configuration computer builder 
        LowConfigurationComputerBuilder builder = new LowConfigurationComputerBuilder();
        //  Create a computer sales center 
        SalesCompany salesCompany = new SalesCompany();
        //  Assign a specific computer builder to complete   The computer   This product 
        Computer computer = salesCompany.buildComputer(builder);
        System.out.println(" Computers built : " + computer );
    }
}

Now the code is quite perfect , That is, our buyers contact the computer sales center , Then the sales center calls the builder of the configuration that the user wants , What we created just now is a “ Low configuration computer builders ”, If we want to switch to a medium configuration computer , How do you do that ?

Now just add a medium configuration computer builder , Realization Builder The abstract class is OK

/**
 *  Low configuration computer 
 */
public class MiddleConfigurationComputerBuilder extends ComputerBuilder {

    private Computer computer;

    public MiddleConfigurationComputerBuilder(){
        computer = new Computer();
    }

    @Override
    void buildCpu() {
        computer.setCpu(" Intel core  i7  processor ");
        System.out.println("buildCpu:  Intel core  i7  processor ");
    }

    @Override
    void buildGraphicsCard() {
        computer.setGraphicsCard("16g Memory ");
        System.out.println("buildGraphicsCard: 16g Memory ");
    }

    @Override
    void buildDisplayScreen() {
        computer.setDisplayScreen("2k 144hz Monitor ");
        System.out.println("buildDisplayScreen: 2k 60hz Monitor ");
    }

    @Override
    Computer getComputer() {
        return computer;
    }
}

Test it

public class Test {
    public static void main(String[] args) {
        MiddleConfigurationComputerBuilder builder = new MiddleConfigurationComputerBuilder();
        //  Create a computer sales center 
        SalesCompany salesCompany = new SalesCompany();
        //  Assign a specific computer builder to complete   The computer   This product 
        Computer computer = salesCompany.buildComputer(builder);
        System.out.println(" Computers built : " + computer );
    }
}

Running results

buildCpu: Intel core i7 processor
buildGraphicsCard: 16g Memory
buildDisplayScreen: 2k 60hz Monitor
Computers built : Computer{cpu=' Intel core i7 processor ', graphicsCard='16g Memory ', displayScreen='2k 144hz Monitor '}

In fact, here is an example of the builder pattern , Let's combine the concepts , Let's take a deeper look at the builder model

3、 ... and Builder pattern

( One ) Concept

Builder pattern : Separate the construction of a complex object from its representation , So that the same build process can create different representations

  • in other words , The product generation process Or say form , yes unchanged Of , And each part is optional , Namely its The internal appearance can change Of , This is also called the separation of change and invariance

  • In this case , Users just need to specify the type of build to get them , And the specific process and details don't need to be known

( Two ) Advantages and disadvantages

First , This mode has good encapsulation , Construction and presentation are separated , Each builder is independent of each other , It is good for decoupling and expansion , accord with “ Opening and closing principle ” At the same time, when the client calls , No need to know the product details

But it is also because of the constant part of the product generation process , It limits its use , At the same time, if something changes inside the product in the future , Then the builder has to modify it as well , Maintenance costs are not small

( 3、 ... and ) structure

According to the structure diagram above , Let's talk about the four roles ( except Client Beyond the caller )

  • Product( Product role ): Complex objects made up of multiple components , The computer in the above example
  • Builder( Abstract builder ): An interface that contains abstract methods for creating the various components of a product / abstract class , Generally, it also contains a method to return the result , As mentioned above ComputerBuilder class
  • ConcreteBuilder( Specific builder ):Builder Implementation class of , As mentioned above Low configuration computer builders and Medium configuration computer builder
  • Director( commander ): Call the component construction and assembly methods in the builder object , To create a complex object
    • There is no specific product information in the commander
    • It isolates the production process of customers and objects

( Four ) Applicable scenario

  • The order affects the results of the same method , Like building a house , The foundation should be laid first , And then steel and cement
  • The same object can assemble different parts or parts , At the same time, the results are different
  • Product classes have complex internal structures , And these product objects have common features

版权声明
本文为[BWH_Steven]所创,转载请带上原文链接,感谢