C++如何为各种类似的实体使用固定的类层次结构,例如公司1,2,3的employee-Manager

zbq4xfa0  于 2023-07-01  发布在  其他
关注(0)|答案(2)|浏览(114)

很难给这个问题一个合适的标题让我来解释一下这个场景。
我有一个类Employee,(Employee的)子类Manager

  • *Employee**类中有各种方法(和数据成员),涉及到工资单、员工明细、考核等。同样,Manager也有多种方法。
class Employee {
    string name, address, empId;
    int salary;
    Dept dept;
public:
    void [Get/Set]Name();
    void GetEmpid();
    void SetSalary();
    virtual void StartOnboarding();
    virtual void startOfboarding();
    virtual void startAppraisal();
};

class Manager : public Employee {
    list teamList;
    int appraisalBudget;    
public:
    int [Get/Set]AppraisaBudget();
    int [Add/Delete]EmployeeInTeam(emp);
    void StartTeamAppraisal();
};

假设我有很多公司,比如Company 1、Company 2等。并且将来可以添加更多。员工或经理可以属于公司1、公司2等。
公司1的员工和经理将具有与上述类似的关系,公司2也是如此。但是它们将有不同的方法来处理可用的方法。就像公司1的员工的startOnboarding()将不同于公司2的员工,类似地,公司1的经理的StartTeamAppraisal()将不同于公司2的经理。
现在,对该场景建模的一种方法是为每个公司创建不同的Employee子类,如EmployeeCompany 1EmployeeCompany 2,并为每个公司创建类似的Manager子类,如ManagerCompany 1ManagerCompany 2等。
不同公司的员工课程-

class EmployeeCompany1 : public Employee {
    int tasksDone;
    int clientsMeetingsDone;
    int appreciationsReceived
public:
        // Company1 specific implementation of following
    virtual void StartOnboarding() { ... }
    virtual void startOfboarding() { ... }
    virtual void startAppraisal()  { ... }
};

class EmployeeCompany2 : public Employee {
    int bugSolved;
    int featureDeveloped;
public:
        // Company2 specific implementation of following
    virtual void StartOnboarding() { ... }
    virtual void startOfboarding() { ... }
    virtual void startAppraisal()  { ... }
};

但在上述情况下,EmployeeCompany[1,2,..]将是Employee的子类,Manager已经是Employee的子类,但它们(EmployeeCompany[1,2..]和Manager)并不在同一级别,因为行为被考虑。所以在设计上有一些缺陷。
如果我们对ManagerCompany 1做类似的处理,那么它必须是EmployeeCompany 1的子类,但它也必须是Manager的子类,如下所示-

class ManagerCompany1 : public EmployeeCompany1, public Manager {
protected:
    int company1specificData;
public:
    virtual void StartTeamAppraisal() {
    // make use of data member of EmployeeCompany1 and other things specific to company1
    }
};

class ManagerCompany2 : public EmployeeCompany2, public Manager {
protected:
    int company2specificData;
public:
    virtual void StartTeamAppraisal() {
    // make use of data member of EmployeeCompany2 and other things specific to company2
    }
};

1.我觉得我的设计有缺陷,我描述的场景将是面向对象设计文献中定义良好的场景。
1.我正在寻找一个更好的设计方法,以C++以上场景模型社区的帮助。
1.你也可以为这个问题建议一个更好的标题。

pzfprimi

pzfprimi1#

从设计的Angular 来看,你的想法似乎落后于我。
员工是一个人。公司(或部门)不是个人的一部分-它是一个独特的(逻辑)实体,管理员工的集合,分配/撤销管理权,支付工资,并启动入职和离职流程。该公司还出于自己的目的,将员工ID与每个员工相关联-它不会(通常)在每个员工的额头上纹一个ID,因此ID不是员工的财产。
此外,一个人可能有不止一份工作-例如,为多家公司兼职。但是,该人员与公司1的关系不会(具体)影响该人员与公司2的关系。一个人可以是公司1的经理,但(比如,如果公司1破产,不支付工资),也可以是公司2的看门人。
经理和其他员工之间的唯一真实的区别是他们有不同的角色。部门有许多角色,并将一个或多个角色与每个员工相关联。
考虑到这一点,我会做一些像

class Employee
 {
      // attributes, setters, getters for name, address
 };

 class Department
 {
     public:
     void OnBoard(Employee &);    // set up pay, employee ID, etc
     void Offboard(Employee &);
     
     void PayAllEmployees();  //  pay every employee

     RoleDescription CreateRole(RoleAttributes);   // different roles for staff, cleaners, managers

     void AssignRole(EmployeeID, RoleDescription);
     void UnassignRole(EmployeeID, RoleDescription);

 };

然后将公司构建为部门的集合。
如果不同的部门或公司有不同的程序(比如,入职、入职、离职等),那么就把相关的函数设为虚拟的,并在派生类中重写它们。它不是一个部门一个班(或一个公司一个班)。它是每个部门(或公司)类别的一个类。例如,会计部门可能有不同的程序比一个部门与工厂业务有关。审计公司可能有一套不同于汽车制造商的部门。
作为虚拟功能的替代方案,您还可以使用模板(例如,公司可能由一组部门组成,每个部门可能具有一组不同的属性)。

0md85ypi

0md85ypi2#

我认为模板是解决这个问题的好办法。试着找出不同公司之间的不同之处,并生成一个通用的界面。

class Company {
public:
  struct StartOnboardingParams { ... };
  virtual static StartOnboardingParams getSOBParams(...);
};

class Company1 : public Company { ... };

template <typename CompanyType>
class Employee {
static_assert(std::is_base_of<Company, CompanyType>::value, "CompanyType must be derived from Company");
public:
   virtual void StartOnboarding() { /* here you can use Company::getSOBParams */ }
}

template <typename Company>
class Manager : public Employee<Company> { ... };

在本例中,Company1Manager只继承自Company1Employee,而不继承自任何其他公司的员工,这解决了设计中的缺陷。
模板化主题的确切假设和内容可能并不简单,需要在界面中进行一些更改,但通常这种方法应该是有帮助的。

相关问题