对于具有固定数量字段的对象,使用一个 setter 方法还是使用多个方法更好?

Is it better to have one setter method or multiple for objects with a fixed number of fields?

我有一个 class,其中有一个对象类型的成员变量。该对象具有固定数量的字段。我正在尝试决定是否应该使用一个 setter 函数或多个函数来改变这些字段。

为了使问题更具体,我写了以下内容 class 以两种不同的方式模拟一个简单的组织管理结构:

  1. 多个Setter函数

    class Management {
        constructor() {
            this.numberOfManagers = 100;
            this.salaryDetails = {
                regionalManagerSalary: 80000,
                stateManagerSalary: 110000,
                executiveManagerSalary: 200000
            };
        }
    
        setRegionalManagerSalary(salary) {
            this.salaryDetails.regionalManagerSalary = salary;
        }
    
        setStateManagerSalary(salary) {
            this.salaryDetails.stateManagerSalary = salary;
        }  
    
        setExecutiveManagerSalary(salary) {
            this.salaryDetails.executiveManagerSalary = salary;
        }
    }
    
    const management = new Management();
    management.setRegionalManagerSalary(100000);
    management.setStateManagerSalary(120000);
    management.setExecutiveManagerSalary(210000);
    
  2. 一个Setter函数

    class Management {
        constructor() {
            this.numberOfManagers = 100;
            this.salaryDetails = {
                regionalManagerSalary: 80000,
                stateManagerSalary: 110000,
                executiveManagerSalary: 200000
            };
        }
    
        setManagerSalary(typeOfManagerSalary, salary) {
            this.salaryDetails[typeOfManagerSalary] = salary;
        }
    }
    
    const management = new Management();
    management.setManagerSalary('regionalManagerSalary', 100000);
    management.setManagerSalary('stateManagerSalary', 120000);
    management.setManagerSalary('executiveManagerSalary', 210000);
    

实施 1. 会更好还是实施 2. 会更好?

我的建议是使用一种方法 setSalaryDetails,它将薪水对象作为您可以直接设置的输入。像 -

setSalaryDetails(salaryDetails){this.salaryDetails = salaryDetails; }

当您调用此方法时,您可以使用您将传递给它的那些字段集来适当地创建此对象。

如果不牺牲很多可写性,我将始终考虑更高可读性的方法。第二个更通用,但第一个更清楚。

所以我认为第一个更好,因为它更清楚 salaryDetails 中只有 3 个字段。考虑一下你不是作者,当你看到第二个时,你不知道 salaryDetails 中会有多少字段,因为有人可以在某处调用 management.setManagerSalary('someNewSalary', 100000); 来添加一些新字段。

除非您有多个管理对象,并且每个管理对象都可能在 salaryDetails 下有一些特定字段,否则我认为第二种方法不会更好。

最好不要 setter。在构造函数中初始化所有必需的属性(让构造函数为此需要参数)。

您发布的代码不是 OOP,而是伪装的过程代码。如果你想让它成为 OOP,那么代码必须留在数据所在的位置,即在 class.

作为第一个改进步骤,您的代码应如下所示:

class Management {
    constructor(nb, regionalSalary, stateSalary, executiveSalary) {
        this.numberOfManagers = nb;
        this.salaryDetails = {
            regionalManagerSalary: regionalSalary,
            stateManagerSalary: stateSalary,
            executiveManagerSalary: executiveSalary
        };
    }
}

const management = new Management(100, 100000, 120000, 210000);

更短、更清晰、更不容易出错。

您发布的片段不足以说明您想要实现的目标,但构造函数的新签名告诉我您将太多职责混合到一个 class。

更简洁的设计是为每种经理类型使用单独的 classes:

/* abstract */ class Manager {
    constructor(salary) {
        this.salary = salary;
    }
}

class RegionalManager extends Manager { }
class StateManager extends Manager { }
class ExecutiveManager extends Manager { }

class Management {
    constructor(nb, regionalManager, stateManger, executiveManager) {
        this.numberOfManagers = nb;
        this.managers = {
            regionalManager: regionaManager,
            stateManager: stateManager,
            executiveManager: executiveManager
        };
    }
}

const management = new Management(
    100,
    new RegionalManager(100000),
    new StateManager(120000),
    new ExecutiveManager(210000)
);

您现在可以在 class Manager 中实现所有管理器类型通用的逻辑,在其 class 中实现每个管理器类型特定的逻辑以及处理在 class Management 中按数量管理经理,而不关心他们的个人特征。这样代码使用更少的 ifswitch 条件,更容易阅读、理解和进一步开发。