For developers, design patterns can sometimes be a barrier, but design patterns can be very useful, beyond which you can move up a notch.In the development of Android, it is necessary to know some design patterns, because design patterns are ubiquitous in Android source code.For students who want to study design mode systematically, here is a Book recommended, Dahua Design Mode.
Android Common Design Mode Series:
Basic Object-Oriented Features
Object-oriented design principles
Singleton mode
Template mode
Adapter mode
Factory Mode
proxy pattern
Prototype mode
Policy Mode
Build mode
Observer mode
Decorator Mode
Mediation mode
facade
Build mode
Build mode is one of the most common design modes. Write a note to record my learning process and experience.
Start by understanding some of the definitions of Build patterns.
Separating the construction of a complex object from its representation allows the same construction process to create different representations
But after looking at this definition, there is no egg to use, and you still don't know what the Builder design pattern is.In this individual's attitude is to learn the design pattern such thing, do not care too much about its definition, the definition is often more abstract, the best example to learn it is through the sample code.
We present the Builder pattern through an example.Suppose there is a Car class where we build a large number of cars. There are many attributes in this Car class, such as color, price, brand, displacement, and so on, and we allow these values not to be set, that is, null, which is defined as follows.
public class Car { Color color; double price; String brand; String displacement; public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getDisplacement() { return displacement; } public void setDisplacement(String displacement) { this.displacement = displacement; } }
Then we might define a construction method for convenience.
public Car(Color color, double price, String brand, String displacement) { this.color = color; this.price = price; this.brand = brand; this. displacement = displacement; }
Sometimes, you just want to pass some parameters, and you will define similar constructions as follows.
public Car(Color color) { this.color = color; } public Car(Color color, double price) { this.color = color; this.price = price; } public Car(Color color, double price, String brand) { this.color = color; this.price = price; this.brand = brand; }
So you can create all the objects you need in this way
Person p2=new Person(Color.read); Person p3=new Person(Color.blue,180000); Person p4=new Person(Color.green,21180, "Xiao Peng"); Person p5=new Person(Color.white,17170,"Ferrari","4.0L");
You can imagine the disadvantage of creating this way. If all four parameters are of the same data type, what exactly do the parameters mean? That's readable.Another problem is that writing this constructor can be cumbersome when you have a lot of parameters, so if you try Builder mode from a different angle, you'll see that the code becomes readable all at once.
We add a static inner class Builder class to Car and modify the constructor of the Car class with the following code.
public class Car { Color color; double price; String brand; String displacement; public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public String getDisplacement() { return displacement; } public void setDisplacement(String displacement) { this.displacement = displacement; } private Car(Builder builder) { this.color = builder.color; this.price = builder.price; this.brand = builder.brand; this. displacement = builder.displacement; } public static class Builder { Color color; double price; String brand; String displacement; public Builder color(Color color){ this.color=color; return this; } public Builder price(double price){ this.price=price; return this; } public Builder brand(String brand){ this.brand=brand; return this; } public Builder displacement(String displacement){ this.displacement=displacement; return this; } public Car build() { return new Car(this); } } }
In this way, we will not be confused by the various inputs of the Car class constructor.
In addition, member functions in the Builder class return the Builder object itself, allowing it to support chain calls, greatly enhancing code readability.So we can create Car classes like this.
new Car.Builder().color(Color.BLUE) .price(129800) .pailiang("1.5T") .brand("Xiao Peng") .build();
Do you think the creation process will become so clear all of a sudden?The value corresponds to an attribute that is clear at a glance and is much more readable.
To summarize, let's summarize the main points of the build pattern:
1. Define a static internal class Builder, internal member variables are the same as external classes
2. The Builder class uses a series of methods to assign member variables and return the current object itself (this)
3. The Builder class provides a way to create an external class (build, create...)This method calls a private constructor of an external class internally, and the input is the internal class Builder
4. External classes provide a private constructor for internal classes to call, in which member variables are assigned values corresponding to the variable in the Builder object
Patterns are widely used
In fact, in Android, the Builder mode is also used a lot.For example, the creation of common dialogs
AlertDialog.Builder builder=new AlertDialog.Builder(this); AlertDialog dialog=builder.setTitle("Title") .setIcon(android.R.drawable.ic_dialog_alert) .setView(R.layout.myview) .setPositiveButton(R.string.positive, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .setNegativeButton(R.string.negative, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }) .create(); dialog.show();
Moreover, various third-party frameworks also make extensive use of the Builder model
For example, GsonBuilder in Gson, the code is too long to paste. You are interested in seeing the source code for yourself. Here is only how to use its Builder.
GsonBuilder builder=new GsonBuilder(); Gson gson=builder.setPrettyPrinting() .disableHtmlEscaping() .generateNonExecutableJson() .serializeNulls() .create();
Take a look at OkHttp, the well-known network request framework
Request. Builder builder=new Request.Builder(); Request request=builder.addHeader("","") .url("") .post(body) .build();
summary
Advantage
Builder mode is often used as the builder of a configuration class to separate the construction and representation of a configuration from the target class, to avoid being too many setter methods, and to hide internal details.A more common implementation of Builder mode is through chain calls, which make the code more concise and understandable.
shortcoming
References between internal and external classes may result in higher memory consumption, but this has little impact on current mobile memory.