构造器模式

构造器模式


概述

  • 概念:构造器模式 Builder Pattern1
  • 作用:
    • 使复杂对象的构造算法和它的表示分离,以便同一个构造算法,可以创建不同的表示1
    • 为了将复杂对象的构建过程与它的表示分离2
  • 区别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());
            }
        }
        
        
    • 其他方式

      • 快速添加Builder内部类的方法——PO类上添加 Guava @Builder 注解5
      • 新增参数时不必修改构造方法——PO类上添加 Guava @AllArgsConstructor 注解5
    • 场景二

      • 将复杂对象的构造与对象的属性分离,调用方只需要指定需要调用的类型而无需关注具体的建造过程及细节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));
            }
        }
        
        

  1. 设计模式—构造器模式 ↩︎ ↩︎ ↩︎

  2. Java设计模式–Java Builder模式 ↩︎

  3. 设计模式:Builder模式 ↩︎

  4. 建造者(Builder)模式 的若干使用场景 ↩︎ ↩︎

  5. PO类上添加 Guava @Builder 注解 ↩︎ ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值