我正在研究类似的问题:有办事处和地区。有些(但不是全部)主管局都有销售信息。一些(但不是全部)地区有销售信息。拥有销售信息的办事处始终位于具有销售信息的区域,并且需要区域销售信息。没有销售信息的办公室,不关心他们所在的区域。那么,如何在面向对象的设计中最好地模拟这个?
显然,我们有Office
和District
个类,两者之间存在关系。最直接的实现是将销售信息成员直接包含在这些类中,并且当销售信息不存在时,这些成员为空。但是,对于我来说,将销售信息的实例作为SalesOffice
和SalesDistrict
的实例进行分区似乎更为OO,所以你会有这样的事情:
District <-------- Office
^ ^
| |
SalesDistrict SalesOffice
* GetSalesInfo * GetSalesInfo
* PrintSalesInfo()
这是一个问题:SalesOffice.PrintSalesInfo需要调用SalesOffice和SalesDistrict的GeSalesInfo,并且将District转换为SalesDistrict似乎是一个坏主意。
必须有一个常用的设计模式可以在这里应用,以便:
Office
始终可以知道它属于哪个District
,无论它属于哪个区域。Office
可以访问其所属的District
的销售信息。连连呢?我应该忘记继承并为IsSalesType
和Office
创建District
标记,还是有更好的方法?
[修改:请注意District
和Office
返回的销售信息不是同一类型的信息]
答案 0 :(得分:0)
我想说你不应该把办公室或地区分成有销售和缺课的班级。他们与销售的关系是&#34;有#34;而不是&#34;是&#34;。只需定义一个单独的销售对象,向办公室和区域分别提供对销售对象的引用,并向销售办公室提供对其父区的引用。这样,销售事物只有一个界面,无论他们是在区域还是办公室。
答案 1 :(得分:0)
根据您的解释,SalesDistrict
和SalesOffice
似乎只是销售数据的持有者,并且不会自行添加任何额外的行为。我认为使用继承代表这不是一个好主意。
我认为将区域/办公室的销售信息作为实例变量是一种更好的方法。但是,您不需要使用isSalesType
布尔标志来表示这一点。
如果您使用的是Java 8,那么Optional
数据类型非常适合。这用于表示可以存在或不存在的数据。在这种情况下,您的学区类看起来像:
class District {
...
Optional<SalesInfo> salesInfo;
...
}
每当您需要使用销售信息时,请使用以下方式将其打包:
if(salesInfo.isPresent()) {
...
}
要实例化销售信息对象,请使用:
Optional.of(new SalesInfo(..));
您可以使用Optional.empty()
将其实例化为非销售区/ Office类中的空值。
编辑:
即使您所说的关于打印销售信息的行为很少,我仍然会继续执行上述实施,因为它在概念上更容易理解。在printSalesInfo
类的Office
方法内,您只需执行以下操作:
if(district.getSalesInfo().isPresent()) district.getSalesInfo().get().printSalesInfo();
但是,如果您仍然想完全避免这些检查,请点击此处:
class Office {
private District district;
// constructor
public Office(District district) {
this.district = district;
}
}
class SalesOffice extends Office {
private SalesDistrict district;
private SalesInfo salesInfo;
public SalesOffice(SalesDistrict district) {
super(district);
this.district = district;
}
public void printSalesInfo() {
salesInfo.print();
district.printSalesInfo();
}
}
class District {
....
}
class SalesDistrict extends District {
private SalesInfo salesInfo;
public void printSalesInfo() {
salesInfo.print();
}
}
我们基本上保留对SalesDistrict
类中SalesOffice
对象的引用,尽管父类已经有引用。请注意,我们不会复制对象使用的内存。我们只是保留了额外的参考。当然,这不允许您构建具有非销售区域的销售办公室对象,但这无论如何都是您的假设之一。