1. 构建复杂对象
  2. 分离复杂对象的构建和表示
  3. 同样的构建过程可以创建不同的表示(Simple和Complex)
  4. 无需记忆,自然使用(面向对象的思想)
  5. 与模板方法非常像,模板方法强调的是方法执行,而构建器强调的是对象构建(创建)
  6. 构建器模式与工厂模式的区别

UML类图

image.png

实现

  • 先要有一个初始化对象
  • 再一步一步地去构建里面的成员属性
  • 最后返回构建完毕的对象
  • 链式编程(编程简单),builder经常和这种编程方式一起用
  • 将Builder作为所构建类的内部静态类并将构造方法设为private—->别人new不了Person,只能通过内部静态类来构建Person,相当于是静态工厂
  • 可以指定对象的某一个部分,用不到的用不着每次都传
  • 最后的build();拿到最终定制的对象

    地形类

    ``` package com.mashibing.dp.builder;

// 地形 public class Terrain { // 墙 Wall w; // 堡垒 Fort f; // 地雷 Mine m; }

class Wall { int x, y, w, h;

  1. public Wall(int x, int y, int w, int h) {
  2. this.x = x;
  3. this.y = y;
  4. this.w = w;
  5. this.h = h;
  6. }

}

class Fort { int x, y, w, h;

  1. public Fort(int x, int y, int w, int h) {
  2. this.x = x;
  3. this.y = y;
  4. this.w = w;
  5. this.h = h;
  6. }

}

class Mine { int x, y, w, h;

  1. public Mine(int x, int y, int w, int h) {
  2. this.x = x;
  3. this.y = y;
  4. this.w = w;
  5. this.h = h;
  6. }

}

  1. <a name="DEwjK"></a>
  2. ### 构建器接口

package com.mashibing.dp.builder;

public interface TerrainBuilder { TerrainBuilder buildWall(); TerrainBuilder buildFort(); TerrainBuilder buildMine(); Terrain build(); }

  1. <a name="wiKH8"></a>
  2. ### 复杂构建器实现

package com.mashibing.dp.builder;

public class ComplexTerrainBuilder implements TerrainBuilder { Terrain terrain = new Terrain();

  1. @Override
  2. public TerrainBuilder buildWall() {
  3. terrain.w = new Wall(10, 10, 50, 50);
  4. return this;
  5. }
  6. @Override
  7. public TerrainBuilder buildFort() {
  8. terrain.f = new Fort(10, 10, 50, 50);
  9. return this;
  10. }
  11. @Override
  12. public TerrainBuilder buildMine() {
  13. terrain.m = new Mine(10, 10, 50, 50);
  14. return this;
  15. }
  16. @Override
  17. public Terrain build() {
  18. return terrain;
  19. }

}

  1. <a name="shfZg"></a>
  2. ### 构建器作为静态内部类
  3. - 没有接口只有类
  4. - 没有多种多样的实现类(即只有一种方式的构建器)

package com.mashibing.dp.builder;

public class Person { int id; String name; int age; double weight; int score; Location loc;

  1. private Person() {}
  2. public static class PersonBuilder {
  3. Person p = new Person();
  4. public PersonBuilder basicInfo(int id, String name, int age) {
  5. p.id = id;
  6. p.name = name;
  7. p.age = age;
  8. return this;
  9. }
  10. public PersonBuilder weight(double weight) {
  11. p.weight = weight;
  12. return this;
  13. }
  14. public PersonBuilder score(int score) {
  15. p.score = score;
  16. return this;
  17. }
  18. public PersonBuilder loc(String street, String roomNo) {
  19. p.loc = new Location(street, roomNo);
  20. return this;
  21. }
  22. public Person build() {
  23. return p;
  24. }
  25. }

}

class Location { String street; String roomNo;

  1. public Location(String street, String roomNo) {
  2. this.street = street;
  3. this.roomNo = roomNo;
  4. }

}

  1. <a name="vO7Go"></a>
  2. ### 使用

package com.mashibing.dp.builder;

public class Main { public static void main(String[] args) { TerrainBuilder builder = new ComplexTerrainBuilder(); Terrain t = builder.buildFort().buildMine().buildWall().build(); //new Terrain(Wall w, Fort f, Mine m) //Effective Java

  1. Person p = new Person.PersonBuilder()
  2. .basicInfo(1, "zhangsan", 18)
  3. //.score(20)
  4. .weight(200)
  5. //.loc("bj", "23")
  6. .build();
  7. }

} ```

有必要吗?为什么不用带参的构造方法?

  • 可以用带参的构造方法,没问题,都可以实现
  • 但是用这个模式主要是针对参数非常多的时候
  • 《Effective Java》构建复杂对象建议用构建器模式

随想

  1. 静态内部类可以访问外部类的私有成员方法和变量
  2. 静态内部类初始化的方法、嵌套类的初始化方法