构造器模式
概述
- 概念:构造器模式 Builder Pattern1
- 作用:
- 区别3:
- 模板模式:
- 执行流程由父类决定
- 一旦执行流程变更需要修改父类,违反了开闭设计原则
- 构造模式:执行流程由第三方监工类决定
- 一旦执行流程变更无需修改底层的父子类,只需要修改监控类
- 模板模式:
- 场景1:
-
场景一
-
类的构造方法4
- 当类中有新增属性时,需要扩充构造方法,新增属性,当可选参数过多时,构造对象时就很容易传错参数
- 当类中某些属性可选时,需要定制构造方法,即某些属性可空,某些情况构造对象不需要传值
-
代码示例
package test; import java.io.Serializable; /** * 用户对象 * @author test * 1.创建类 * 2.添加当前类的成员变量,区分变量:必须与可选;添加 Set Get 方法 * 3.创建静态内部类 - 当前的建造类 * 4.添加内部类的成员变量,拷贝外部类的成员变量 * 5.添加外部类构造方法,构造方法入参为内部类,构造方法属性赋值 * 6.添加内部类构造方法,构造方法入参为必须成员变量 * 7.添加内部类成员方法,可选成员变量赋值 * 8.添加内部类建造方法,返回外部类的对象 */ public class User implements Serializable { private static final long serialVersionUID = 3601470141407549788L; /** * 用户编号 required 成员变量 */ private Integer id ; /** * 用户名称 required 成员变量 */ private String name ; /** * 用户年龄 optional 成员变量 */ private Integer age ; /** * 用户身高 optional 成员变量 */ private Integer height ; public Integer getId() { return id; } public String getName() { return name; } public Integer getAge() { return age; } public Integer getHeight() { return height; } private User (UserBuild userBuild){ this.id = userBuild.id ; this.name = userBuild.name ; this.age = userBuild.age ; this.height = userBuild.height ; } public String toString(){ StringBuilder toStringBuilder = new StringBuilder(this.name.length() * 4); toStringBuilder.append("User ").append("id:").append(this.id).append(",name:").append(this.name).append(",age:") .append(this.age).append(",height:").append(this.height); return toStringBuilder.toString(); } /** * User 类建造者类 * @author test */ private static class UserBuild { /** * 用户编号 required 成员变量 */ private Integer id ; /** * 用户名称 required 成员变量 */ private String name ; /** * 用户年龄 optional 成员变量 */ private Integer age ; /** * 用户身高 optional 成员变量 */ private Integer height ; public UserBuild(Integer id ,String name){ this.id = id ; this.name = name ; } public UserBuild age(Integer age){ this.age = age ; return this ; } public UserBuild height(Integer height){ this.height = height ; return this ; } public User build(){ return new User(this); } } public static void main(String[] args) { User user = new UserBuild(1,"2").age(3).height(4).build(); System.out.println(user.toString()); System.out.println(user.getId()); System.out.println(user.getName()); System.out.println(user.getAge()); System.out.println(user.getHeight()); } }
-
-
其他方式
-
场景二
-
将复杂对象的构造与对象的属性分离,调用方只需要指定需要调用的类型而无需关注具体的建造过程及细节4
-
代码示例
package test; import java.io.Serializable; /** * 动物实体类 * 动物身体由头、脚组成 * @author test */ public class Animal implements Serializable{ private static final long serialVersionUID = 2610315450660664668L; /** * 头 */ private Head head = new Head(); /** * 脚 */ private Foot foot = new Foot(); /** * 头的数量 * @param num 数量 */ public void setHeadNum(int num){ head.setNum(num); } /** * 设置脚的数量 * @param num */ public void setFootNum(int num){ foot.setNum(num); } public Head getHead() { return head; } public void setHead(Head head) { this.head = head; } public Foot getFoot() { return foot; } public void setFoot(Foot foot) { this.foot = foot; } public String toString(){ StringBuilder sb = new StringBuilder(""); sb.append("Head num:").append(this.head.getNum()).append(",Foot num:").append(this.foot.getNum()); return sb.toString(); } } package test; import java.io.Serializable; /** * 头 * @author test */ public class Head implements Serializable { private static final long serialVersionUID = 7657725082250430948L; /** * 数量 */ private Integer num ; public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } } package test; import java.io.Serializable; /** * 脚 * @author test */ public class Foot implements Serializable{ private static final long serialVersionUID = -9198575656926734237L; private Integer num ; public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } } package test; /** * 动物构造器 * @author test */ public abstract class AnimalBuilder { protected Animal animal = new Animal(); public abstract void setHeadNum(); public abstract void setFootNum(); } package test; /** * 大象 * @author test */ public class ElephantAnimal extends AnimalBuilder { @Override public void setHeadNum() { animal.setHeadNum(1); } @Override public void setFootNum() { animal.setFootNum(4); } } package test; /** * 蚂蚁 * @author test */ public class AntAnimal extends AnimalBuilder { @Override public void setHeadNum() { animal.setHeadNum(1); } @Override public void setFootNum() { animal.setFootNum(6); } } package test; /** * 指挥者 * @author test */ public class AnimalDirector { private AnimalBuilder animalBuilder; public AnimalDirector(AnimalBuilder animalBuilder){ this.animalBuilder = animalBuilder; } public Animal createAnimal(){ animalBuilder.setFootNum(); animalBuilder.setHeadNum(); return animalBuilder.animal; } } package test; public class AnimalClient { public static void main(String[] args) { AnimalBuilder elephant = new ElephantAnimal(); AnimalDirector director = new AnimalDirector(elephant); Animal animal = director.createAnimal(); System.out.println(animal); } }
-
-
场景三:
-
代码示例
/** * 对象基类 */ public abstract class Operation { public abstract Integer getOperationReuslt(Integer numA,Integer numB); } /** * 加法子类 */ public class AddOperation extends Operation { @Override public Integer getOperationReuslt(Integer numA, Integer numB) { return numA+numB; } } /** * 减法子类 */ public class SubOperation extends Operation { @Override public Integer getOperationReuslt(Integer numA, Integer numB) { return numA - numB; } } /** * 监工类 */ public class Director { private Operation operation; public Director(Operation operation){ this.operation = operation; } public Integer getOperationResult(Integer numA,Integer numB){ return operation.getOperationReuslt(numA,numB); } } /** * 调用类 */ public class BuilderMain { public static void main(String[] args) { AddOperation addOperation = new AddOperation(); Director director = new Director(addOperation); System.out.println(director.getOperationResult(1, 2)); } }
-
-