面向对象编程最佳实践:Employee.GetCars() vs Cars.GetByEmployee()。

8

针对类CompanyEmployeeCar,如何最好地编写方法以检索与公司或员工相关联的汽车?

Employee.GetCars(params...)
Company.GetCars(params...)

或者:

Cars.GetByEmployee(params...)
Cars.GetByCompany(params...)

第一种方法是我通常使用的方法,对我来说似乎最直观。但在看到一个使用第二种方法的大型代码库后,我不得不承认它正在发展壮大。我真正喜欢第二种方法的两个方面是:
  • 它将所有与Car相关的代码组合到一个文件中,使代码更加模块化和易于维护。
  • 有一个直观的逻辑,将任何返回值为Car(或更像List<Car>)的方法分组到Car类中。

是否有涵盖这个问题的最佳实践?


选择一组关于这些事情的惯例和规则,并在每个类似的情况下使它们保持一致,这样做的结果相对不重要。 - Jimmy Hoffa
3
根据你要追踪的内容不同,如果经常是每个员工有4辆车,我会使用 Employee.GetCars(),因为它可以从一开始就缩小范围,但如果有数百万的员工和很少的汽车,我会使用 Cars.GetByEmployee,因为汽车是更小的数据集。我想我是在说我更喜欢:Subset.GetSuperset() 这样更窄的选择就是类。 - Jimmy Hoffa
@Jimmy:除非你喜欢雇佣有感知的车辆,否则我不会把汽车称为员工的子集,但我同意你所说的一般观点。 - jloubert
8个回答

7
我建议在实体类中使用第一种方法。这些方法不应该有任何参数,因为它们只返回所有关联内容。第二种方法涉及一些简单的业务逻辑,应该放在一个辅助类或者CarDAO(如果有的话)中。

太好了,tob提出的建议非常棒!我真的很喜欢这种方法,因为它可以兼顾两全。 - Chris Van Opstal

3

这两种方法对我来说都有些不太合适。为什么Employee类需要了解Car类?为什么Car类需要了解Employee?由于两个类都不需要相互依赖才能正常工作,因此将它们耦合起来是不必要的。我会在某个地方存储一个将员工映射到汽车集合中的字典,以及另一个将公司映射到汽车集合中的字典。


一个员工类为什么要知道员工的年龄或薪水?只需创建一个映射(每个属性一个)!过一段时间后,有人决定将与员工类相关的所有映射收集到一个类中... - Sjoerd
1
这里的问题是耦合。一般来说,只要可能,你应该避免类之间的耦合。 - Peter Ruderman
我甚至没有考虑过这一点,真是个好观点。也许这个方法应该放在一个数据访问层类中,而不是返回一个拥有汽车列表的员工,而应该返回一个行为类似于Tuple<Employee,Car>或Tuple<DBDimension1,DBDimension2>的维度类EmployeeByCar。 - Jimmy Hoffa

2
我认为没有一个单一的解决方案。这取决于你如何争论。如果汽车知道它们归谁负责,那么我会使用第二种方法。但是,如果员工知道他拥有哪些汽车,那么我会使用第一种方法。
然而,个人而言,我更喜欢第一种方法,因为它似乎更容易实现。

2

一个员工拥有一辆(或多辆)汽车,因此每个员工自然知道他使用哪些汽车。但是汽车是否知道或关心谁“拥有”它?我会说不知道。它可能知道谁在驾驶它,但那是另一个问题。

要么汽车确实知道哪个员工拥有它(这感觉不对,这是一种奇怪的has-a关系),要么就必须搜索所有员工才能找到自己,这更糟糕(不合逻辑、速度慢,除了松散耦合外什么都不是)。


1

没有最好的方式。 这取决于您的应用程序需要做什么。 使用相同数据的两个应用程序可以具有完全不同的对象模型,取决于它们的用例。


1

通过Demeter法则逻辑处理来解决这个问题。非常有帮助,对吧!呵呵

这个问题的表述方式总是会在Employee和Car类之间产生耦合。如果你可以将car.GetByEmployee(...)更改为car.GetByDriversLicenseNumber(...)(或类似的内容),那么你就可以解耦这两个类。

最好的方法是减少耦合在一起的对象数量。因此,这完全取决于链中下一个级别对象如何使用Car。

我认为这个问题没有一个正确的答案,一切都取决于当前的情况。


FYI:我知道你没有违反Demeter法则。我建议我们程序员在违规之前应该考虑一下它。 - Jerod Houghtelling

0

都不是。

创建一个名为ICarOwner的接口,由EmployeeCompany(或它们的派生类)实现,然后创建带有属性Car(类型为CarICar)和Owner(类型为ICarOwner)的CarOwnership类。

当您需要查找汽车所有权时,您不需要关心所有者是员工还是公司。您只需要执行CarOwnerships.GetByOwner(ICarOwner)

希望这可以帮助到您。


-1

这都与关系有关。一个员工可以拥有多辆车吗?(1:N)永远不要从N方面引用1方面,那是我的老师说的。其他事情也是如此。如果你有一个1:1,你可以同时操作两个实体。Employee.getCar 和 Car.getOwner ;-)


想使用Employee.getCars()和Car.getDrivers()没有任何问题。而且,你并没有回答问题,问题是关于Car.getCarsByOwner()的。 - relet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接