You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于typeName值实例化类特定属性的最优设计方案咨询

Scalable Solutions for Type-Specific Property Initialization

Great question! Your current if-else approach works for now, but it’s not scalable—adding a new TYPE3 later would force you to modify existing code (breaking the Open/Closed Principle) and leave unused attributes hanging around in CentralClass, which is a recipe for bugs. Let’s walk through two clean, maintainable solutions that fix this, depending on your needs.

This approach splits your mixed attributes into dedicated subclasses, enforcing single responsibility and making it easy to add new types later.

Step 1: Refactor Class Hierarchy

Create an abstract parent class for shared logic, then subclasses for each type with their own properties:

// Abstract base class for all types
public abstract class CentralClass {
    protected final String typeName;

    protected CentralClass(String typeName) {
        this.typeName = typeName;
    }

    public String getTypeName() {
        return typeName;
    }
}

// Subclass for TYPE1 with its exclusive properties
public class Type1Class extends CentralClass {
    private final String a;
    private final String b;
    private final String c;

    public Type1Class(String a, String b, String c) {
        super("TYPE1");
        this.a = a;
        this.b = b;
        this.c = c;
    }

    // Getters for TYPE1 properties
    public String getA() { return a; }
    public String getB() { return b; }
    public String getC() { return c; }
}

// Subclass for TYPE2 with its exclusive properties
public class Type2Class extends CentralClass {
    private final String x;
    private final String y;
    private final String z;

    public Type2Class(String x, String y, String z) {
        super("TYPE2");
        this.x = x;
        this.y = y;
        this.z = z;
    }

    // Getters for TYPE2 properties
    public String getX() { return x; }
    public String getY() { return y; }
    public String getZ() { return z; }
}

Step 2: Implement a Factory Class

The factory handles instantiation based on typeName, so you don’t need scattered if-else checks:

public class CentralClassFactory {
    public static CentralClass createCentralClass(String typeName, Object... args) {
        return switch (typeName) {
            case "TYPE1" -> new Type1Class((String) args[0], (String) args[1], (String) args[2]);
            case "TYPE2" -> new Type2Class((String) args[0], (String) args[1], (String) args[2]);
            default -> throw new IllegalArgumentException("Invalid typeName: " + typeName);
        };
    }
}

Step 3: Usage Example

public class Main {
    public static void main(String[] args) {
        CentralClass type1Instance = CentralClassFactory.createCentralClass("TYPE1", "aValue", "bValue", "cValue");
        CentralClass type2Instance = CentralClassFactory.createCentralClass("TYPE2", "xValue", "yValue", "zValue");

        // Access type-specific properties with type checking (safe in Java 16+)
        if (type1Instance instanceof Type1Class type1) {
            System.out.println("TYPE1 a: " + type1.getA());
        }
    }
}

Why This Works:

  • Single Responsibility: Each subclass only manages properties relevant to its type.
  • Open/Closed Principle: Add new types by creating a new subclass and updating the factory—no changes to existing code.
  • Type Safety: Constructors only accept the required parameters, eliminating accidental invalid property assignments.

Option 2: Builder Pattern with Type Constraints (If You Want to Keep a Single Class)

If you prefer to retain a single CentralClass but still enforce type-specific property rules, use a builder with validation:

Refactored CentralClass with Builder

public class CentralClass {
    private final String typeName;
    private final String x;
    private final String y;
    private final String z;
    private final String a;
    private final String b;
    private final String c;

    // Private constructor—only builder can create instances
    private CentralClass(Builder builder) {
        this.typeName = builder.typeName;
        this.x = builder.x;
        this.y = builder.y;
        this.z = builder.z;
        this.a = builder.a;
        this.b = builder.b;
        this.c = builder.c;
    }

    public static Builder builder(String typeName) {
        return new Builder(typeName);
    }

    public static class Builder {
        private final String typeName;
        private String x;
        private String y;
        private String z;
        private String a;
        private String b;
        private String c;

        private Builder(String typeName) {
            this.typeName = typeName;
        }

        // TYPE1-only property setters with validation
        public Builder a(String a) {
            enforceTypeRestriction("TYPE1");
            this.a = a;
            return this;
        }

        public Builder b(String b) {
            enforceTypeRestriction("TYPE1");
            this.b = b;
            return this;
        }

        public Builder c(String c) {
            enforceTypeRestriction("TYPE1");
            this.c = c;
            return this;
        }

        // TYPE2-only property setters with validation
        public Builder x(String x) {
            enforceTypeRestriction("TYPE2");
            this.x = x;
            return this;
        }

        public Builder y(String y) {
            enforceTypeRestriction("TYPE2");
            this.y = y;
            return this;
        }

        public Builder z(String z) {
            enforceTypeRestriction("TYPE2");
            this.z = z;
            return this;
        }

        // Validate required properties before building
        public CentralClass build() {
            if ("TYPE1".equals(typeName)) {
                if (a == null || b == null || c == null) {
                    throw new IllegalStateException("TYPE1 requires a, b, c to be set");
                }
            } else if ("TYPE2".equals(typeName)) {
                if (x == null || y == null || z == null) {
                    throw new IllegalStateException("TYPE2 requires x, y, z to be set");
                }
            } else {
                throw new IllegalArgumentException("Invalid typeName: " + typeName);
            }
            return new CentralClass(this);
        }

        private void enforceTypeRestriction(String allowedType) {
            if (!allowedType.equals(typeName)) {
                throw new IllegalStateException("Cannot set this property for type " + typeName);
            }
        }
    }

    // Getters for all properties
    public String getTypeName() { return typeName; }
    public String getX() { return x; }
    public String getY() { return y; }
    public String getZ() { return z; }
    public String getA() { return a; }
    public String getB() { return b; }
    public String getC() { return c; }
}

Usage Example

public class Main {
    public static void main(String[] args) {
        // Valid TYPE1 instance
        CentralClass type1 = CentralClass.builder("TYPE1")
                .a("aVal")
                .b("bVal")
                .c("cVal")
                .build();

        // Valid TYPE2 instance
        CentralClass type2 = CentralClass.builder("TYPE2")
                .x("xVal")
                .y("yVal")
                .z("zVal")
                .build();

        // This will throw an exception (trying to set x for TYPE1)
        // CentralClass invalid = CentralClass.builder("TYPE1").x("xVal").build();
    }
}

Why This Works:

  • Single Class: Keeps all properties in one place if that’s your preference.
  • Runtime Validation: Prevents setting invalid properties for a given type.
  • Readable Syntax: Chained builder calls make instance creation easy to follow.

Which to Choose?

  • Go with Inheritance + Factory if different types have distinct business logic (not just different properties)—it’s more flexible for future changes.
  • Use the Builder Pattern if you only need to restrict properties but keep shared logic in a single class.

内容的提问来源于stack exchange,提问作者Akshit Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 12:57:39