如何构造对象:OOP,组合

时间:2014-06-30 20:45:22

标签: oop inheritance composition

我有一个对象,我们称之为Request,它与其他几个对象有关联,如:

Employee submitter;
Employee subjectsManager;
Employee pointOfContact;

以及一些值属性,如字符串,日期和枚举。

现在,我还需要跟踪另一个对象,主题,但这可能是3种不同类型的人之一。为简单起见,我们只谈两种类型:员工和顾问。他们的数据来自不同的存储库,他们有不同的字段集,有些重叠。所以说一个员工有一个

String employeeName;
String employeeId;
String socialSecurityNumber;

而顾问

String consultantName;
String socialSecurityNumber;
String phoneNumber;

一个可怕的想法是,Request既有Consultant又有Employee,setSubject(Consultant)分配一个,setSubject(Employee)分配另一个。听起来很糟糕。我的主要目标之一是避免“如果主题是这种类型,那么就这样......”逻辑。

我的想法是,也许EmployeeRequest和ConsultantRequest应该扩展Request,但我不确定setSubject是如何工作的。我希望它是基类中的抽象方法,但我不知道签名是什么,因为我不知道参数的类型。

那么从界面角度来看它是有意义的。一个重要的接口是这些Request对象将被传递给我不拥有的单个Web服务。我将不得不以一种部分有意义的复杂方式映射对象的字段。对于像name和SSN这样的字段,映射很简单,但是许多不在所有类型的人之间排列的字段被转储到连接字符串AdditionalInfo字段(wump wump)中。所以他们都有一个getAdditionalInfo方法,一个getName等,如果有任何字段没有排列,他们可以做一些特别的事情。

这让我觉得Request本身不一定是子类,但可以包含对ISubjectable(或其他)的引用,它实现了获取值通过Web服务发送所需的接口。这听起来相当不错,并且可以防止很多“如果主题是员工那么这样做......”

但是,我仍然有时需要访问只有特定类型主题的附加字段,例如在显示或编辑页面上,这样才能让我回到“如果主题是员工的实例”那么转到编辑员工页面......“这可能是不可避免的,如果是这样我就可以了。

为了完整起见,我会提到“所有可能领域的联合”方法 - 不要以为我也会关心那个。

界面接近最合理还是我错了?感谢。

1 个答案:

答案 0 :(得分:0)

想到一个通用的解决方案;也就是说,如果您使用的语言支持它:

class Request<T extends Subject> {
    private T subject;

    public void setSubject(T subject) {
        this.subject = subject;
    }

    public T getSubject() {
        return subject;
    }
}

class EmployeeRequest extends Request<Employee> {
    // ...
}

class ConsultantRequest extends Request<Consultant> {
    // ...
}

您可以像在帖子中描述的那样使setSubject方法抽象化,然后在子类中单独实现它。或者您甚至可能不需要继承Request类:

Request<Employee> employeeRequest = new Request<>();
employeeRequest.setSubject(/* ... */);
// ...
int employeeId = employeeRequest.getSubject().getEmployeeId();