我们在使用Retrofit等这些第三方框架的时候,发现他们的使用都很方便,比如Retrofit retrofit = new Retrofit.Builder().build(),和我们通常直接new一个对象不同,他是交给Builder类,通过build()函数来构造一个Retrofit对象。
刚开始使用,可能不太明白,明明可以直接new出来,为什么要交给Builder来构造呢?那么通过学习了构造者设计模式,才明白,原来当使用者构造对象时,构造函数的参数一般大于等于五个,就可以考虑使用构造者设计模式,这样编写代码的好处,在于结构清晰,也易于扩展。
在实际工作中,我们可能接触了很多这种链式创建对象的场景,比如AlertDialog,发现这种代码在使用的时候,真的很香,不仅实现了参数传递的灵活性,也避免了因参数过多造成的混乱。总之,除了使用官方封装的这些类以外,自己在实现代码的同时,也想要动手实现一个建造者设计模式。
下面我们以电脑为例,创建一个抽象类Computer,我们想想,电脑都有什么属性,品牌,型号,操作系统,用途,类型,名字等等。这些属性如果都用构造方法实现的话,会很长,而且也不易于扩展,不够灵活。
- static class Computer{
- String name;
- String brand;
- String os;
- String display;
- String type;
- String use;
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setBrand(String brand) {
- this.brand = brand;
- }
-
- public void setOs(String os) {
- this.os = os;
- }
-
- public void setDisplay(String display) {
- this.display = display;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public void setUse(String use) {
- this.use = use;
- }
- }
比如,我们需要创造一个macbook笔记本,用传统思维,直接创造一个类,然后继承Computer,通过构造函数的方法重载,完成各种需求的笔记本。这样一套下来,代码臃肿不说,也不宜与后期的维护,如果有新的属性,又要重载一个构造函数,比较繁琐。
- static class MacBook extends Computer{
- public MacBook() {
- }
-
- // ……
- //各种构造函数
- // ……
-
- @Override
- public String toString() {
- return "MacBook{" +
- "name='" + name + '\'' +
- ", brand='" + brand + '\'' +
- ", os='" + os + '\'' +
- ", display='" + display + '\'' +
- ", type='" + type + '\'' +
- ", use='" + use + '\'' +
- '}';
- }
- }
如果有一个专门的类,来创建不同需求的笔记本,这个问题就能很好的解决。
那么这个专门的类就是Builder类,通过构造者设计模式进行优化,我们这里具体到了MacBook笔记本,在实际开发工作中,这个可以使用泛型T代替,更加灵活。
- static abstract class Builder {
- abstract MacBookBuilder builderName(String name);
-
- abstract MacBookBuilder builderBrand(String brand);
-
- abstract MacBookBuilder builderOs(String os);
-
- abstract MacBookBuilder builderType(String type);
-
- abstract MacBookBuilder builderUse(String use);
-
- abstract MacBookBuilder builderDisPlay(String display);
-
- abstract Computer build();
-
- }
接下来,我们将利用MacBookBuilder 来构造笔记本,代码如下:
- static class MacBookBuilder extends Builder{
-
- MacBook macBook = new MacBook();
-
- @Override
- MacBookBuilder builderName(String name) {
- macBook.name = name;
- return this;
- }
-
- @Override
- MacBookBuilder builderBrand(String brand) {
- macBook.brand = brand;
- return this;
- }
-
- @Override
- MacBookBuilder builderOs(String os) {
- macBook.os = os;
- return this;
- }
-
- @Override
- MacBookBuilder builderType(String type) {
- macBook.type = type;
- return this;
- }
-
- @Override
- MacBookBuilder builderUse(String use) {
- macBook.use = use;
- return this;
- }
-
- @Override
- MacBookBuilder builderDisPlay(String display) {
- macBook.display = display;
- return this;
- }
-
- @Override
- Computer build() {
- return macBook;
- }
- }
好了,我们通过测试类,测试一下,附上完整代码:
- package com.example.lib;
-
-
- public class BuilderTest {
-
- public static void main(String[] args) {
-
- Computer macbook = new MacBookBuilder()
- .builderName("macbook 2023")
- .builderOs("mac/os")
- .builderBrand("apple")
- .builderType("Laptops")
- .builderDisPlay("Retina显示器")
- .builderUse("studyProgram")
- .build();
-
- System.out.println(macbook.toString());
- }
-
-
- static class Computer{
- String name;
- String brand;
- String os;
- String display;
- String type;
- String use;
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setBrand(String brand) {
- this.brand = brand;
- }
-
- public void setOs(String os) {
- this.os = os;
- }
-
- public void setDisplay(String display) {
- this.display = display;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public void setUse(String use) {
- this.use = use;
- }
- }
-
-
- static class MacBook extends Computer{
- public MacBook() {
- }
-
- @Override
- public String toString() {
- return "MacBook{" +
- "name='" + name + '\'' +
- ", brand='" + brand + '\'' +
- ", os='" + os + '\'' +
- ", display='" + display + '\'' +
- ", type='" + type + '\'' +
- ", use='" + use + '\'' +
- '}';
- }
- }
-
-
- static abstract class Builder {
- abstract MacBookBuilder builderName(String name);
-
- abstract MacBookBuilder builderBrand(String brand);
-
- abstract MacBookBuilder builderOs(String os);
-
- abstract MacBookBuilder builderType(String type);
-
- abstract MacBookBuilder builderUse(String use);
-
- abstract MacBookBuilder builderDisPlay(String display);
-
- abstract Computer build();
-
- }
-
- static class MacBookBuilder extends Builder{
-
- MacBook macBook = new MacBook();
-
- @Override
- MacBookBuilder builderName(String name) {
- macBook.name = name;
- return this;
- }
-
- @Override
- MacBookBuilder builderBrand(String brand) {
- macBook.brand = brand;
- return this;
- }
-
- @Override
- MacBookBuilder builderOs(String os) {
- macBook.os = os;
- return this;
- }
-
- @Override
- MacBookBuilder builderType(String type) {
- macBook.type = type;
- return this;
- }
-
- @Override
- MacBookBuilder builderUse(String use) {
- macBook.use = use;
- return this;
- }
-
- @Override
- MacBookBuilder builderDisPlay(String display) {
- macBook.display = display;
- return this;
- }
-
- @Override
- Computer build() {
- return macBook;
- }
- }
- }
构造者设计模式,在安卓开放当中非常常见,也是一种创建型设计模式,类似与工厂模式,但不同于工厂模式。主要优点如下: