MST

星途 面试题库

面试题:Java建造者模式如何优化传统构造方式在扩展性方面的不足

假设你正在开发一个游戏角色创建系统,初始使用传统构造方式,随着游戏更新,需要不断添加新的角色属性及创建逻辑。分析传统构造方式在此场景下扩展性的问题,然后说明如何运用Java建造者模式来优化扩展性,并给出关键代码示例。
19.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

传统构造方式扩展性问题分析

  1. 构造函数臃肿:随着新角色属性不断添加,构造函数参数会越来越多,导致构造函数变得冗长、难以维护。例如,最初角色只有姓名和性别属性,构造函数为Role(String name, String gender),若新增年龄、职业、种族等属性,构造函数就变成Role(String name, String gender, int age, String occupation, String race),参数数量大幅增加。
  2. 调用复杂:调用构造函数时,需要记住参数的顺序和含义,容易出错。特别是当有多个相似类型参数时,如Role(String name, int age, int level, String gender),调用者可能混淆agelevel参数。
  3. 灵活性差:若想在创建角色过程中增加特定的创建逻辑,如根据不同种族设置初始生命值等,在传统构造方式下,需要修改构造函数,这违背了开闭原则,对已有代码影响较大。

Java建造者模式优化扩展性说明

  1. 分离创建和表示:建造者模式将对象的创建过程和对象的表示分离。在角色创建系统中,角色的属性构成是其表示,而如何创建这些属性及组合成角色是创建过程。通过分离两者,当角色属性或创建逻辑改变时,不会相互影响。
  2. 提高可维护性:每个具体建造者负责特定类型角色的创建,代码逻辑清晰。例如,创建战士角色的建造者和创建法师角色的建造者分开,各自处理自己角色相关的属性和创建逻辑,当修改战士角色创建逻辑时,不会影响法师角色的创建。
  3. 遵循开闭原则:新增角色类型或修改角色创建逻辑时,只需新增或修改具体建造者类,无需修改原有代码。例如,新增一个刺客角色,只需创建一个刺客角色建造者类,实现相应的创建逻辑,不影响其他已有的角色创建逻辑。

关键代码示例

  1. 角色类
public class Role {
    private String name;
    private String gender;
    private int age;
    private String occupation;
    private String race;

    // 省略getter和setter方法

    @Override
    public String toString() {
        return "Role{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age=" + age +
                ", occupation='" + occupation + '\'' +
                ", race='" + race + '\'' +
                '}';
    }
}
  1. 建造者接口
public interface RoleBuilder {
    void buildName();
    void buildGender();
    void buildAge();
    void buildOccupation();
    void buildRace();
    Role getRole();
}
  1. 具体建造者类
public class WarriorRoleBuilder implements RoleBuilder {
    private Role role = new Role();

    @Override
    public void buildName() {
        role.setName("Warrior Name");
    }

    @Override
    public void buildGender() {
        role.setGender("Male");
    }

    @Override
    public void buildAge() {
        role.setAge(25);
    }

    @Override
    public void buildOccupation() {
        role.setOccupation("Warrior");
    }

    @Override
    public void buildRace() {
        role.setRace("Human");
    }

    @Override
    public Role getRole() {
        return role;
    }
}
  1. 指挥者类
public class RoleDirector {
    private RoleBuilder roleBuilder;

    public RoleDirector(RoleBuilder roleBuilder) {
        this.roleBuilder = roleBuilder;
    }

    public Role constructRole() {
        roleBuilder.buildName();
        roleBuilder.buildGender();
        roleBuilder.buildAge();
        roleBuilder.buildOccupation();
        roleBuilder.buildRace();
        return roleBuilder.getRole();
    }
}
  1. 使用示例
public class Main {
    public static void main(String[] args) {
        RoleBuilder warriorBuilder = new WarriorRoleBuilder();
        RoleDirector director = new RoleDirector(warriorBuilder);
        Role warrior = director.constructRole();
        System.out.println(warrior);
    }
}