Java 按返回类型或参数组织方法?

Java 按返回类型或参数组织方法?,java,oop,Java,Oop,我在阐述这个问题时有点困难。对于不同的类型,如何组织遍历关系以转换为不同类型的方法需要考虑哪些因素 例如,在原谅精确建模的同时,假设有三个类,它们之间都有多对多关系:汽车,车库和停车通行证 一辆车可以有多张停车通行证 停车通行证允许汽车停在车库里 同一通行证可用于多个车库 同一通行证可供多辆车使用 我将使用伪Java语法,但我不认为这是特定于语言的(甚至是特定于OOP的,尽管可能更相关)。如果有人想知道汽车可以停在什么车库里,以下方法似乎同样有效: 询问汽车对象的车库: Car { C

我在阐述这个问题时有点困难。对于不同的类型,如何组织遍历关系以转换为不同类型的方法需要考虑哪些因素

例如,在原谅精确建模的同时,假设有三个类,它们之间都有多对多关系:
汽车
车库
停车通行证

  • 一辆车可以有多张停车通行证
  • 停车通行证允许汽车停在车库里
  • 同一通行证可用于多个车库
  • 同一通行证可供多辆车使用
我将使用伪Java语法,但我不认为这是特定于语言的(甚至是特定于OOP的,尽管可能更相关)。如果有人想知道汽车可以停在什么车库里,以下方法似乎同样有效:


询问
汽车
对象的车库:

Car {
   Collection<Garage> getGarages();
}
无论哪种方式,对象都需要通过
ParkingPass
类来解析关系映射,因此一个对象和另一个对象之间没有直接转换

看看Java之类的例子(它接受与类类型大致相同的参数,并生成不同的类),使用
Car.getGarages()
方法似乎是合理的。或者,看看Guava,它接受一个“不同”类型的参数,并返回一个与类类型相同的值

是否有最佳实践指导如何决定将方法放在何处?可能的解决办法包括:

  • 将该方法放入与该方法的返回类型匹配的类中。这意味着类“知道”如何将其他对象转换为它们自己
  • 将该方法放入与该方法的参数匹配的类中。这意味着类“知道”如何将自身转化为其他对象
  • 引入一个实用程序类,该类使用一个对象,执行一些特定于域的操作,并返回另一个对象

  • 所有这些方法的一个常见缺陷是排列问题——如果你的类形成一个高度连通的图,那么无论选择哪种解决方案都会变得很大。

    从面向对象的角度来看,问一辆
    汽车可以停在什么车库是很自然的。当然,询问a
    是不太自然的,因为它要求被询问的
    Garage
    实例了解其他车库。

    询问
    汽车
    是更好的解决方案,但这取决于语义,取决于您对模型的实际思考方式。您还可以介绍这两种方法,其中一种方法只是询问另一种方法的实际值。所以问题是哪种方法才是真正的信息来源

    对于这种特殊情况,为什么不将
    ParkingPass
    建模为一个类,该类实际上服务于自身包含的信息

    class ParkingPass {
        Collection<Garage> for(Car);
    }
    
    class停车通行证{
    收集(汽车);
    }
    

    对我来说,这似乎是正确的做法

    我不认为如何组织方法的问题可以用“按返回类型”、“按参数”等来回答。相反,我认为方法所属的位置(以及通常如何组织代码)始终取决于代码所表示的模型,因此,人们应该问自己的问题是:代码如何才能最好地表示我试图实现的模型?。既然你问了这个问题,这可能是你的目标,所以我想我们已经同意了。但让我详细说明一下

    让我们以汽车和车库为例。所以我们想知道汽车可以停在什么车库里。谁来决定汽车是否可以停在车库里?我想说的是,最终是车库决定是否允许容纳一辆汽车,因此在车库类中放置一个方法来决定一辆汽车是否允许停放在车库中可能是有意义的。这取决于什么条件,可能是停车证、汽车牌照、颜色或其他,这是车库唯一关心的问题

    但现在我们拥有一张停车通行证,这可能会影响我们是否被允许进入车库。这是否意味着停车通行证也可以决定是否允许我们将车停在车库中,我们在车库类中使用的验证方法也可以进入停车通行证类?不,停车通行证只能声明允许汽车停在车库中,但此声明只有在车库同意的情况下才有效,因此车库类中的验证方法属于车库类

    当然,查询停车通行证的条款仍然是有用的,实现这一点与将验证方法放在garage类中并不矛盾,因为这两个构造表示不同的内容,我们只需要注意它。那么,我们如何实施停车通行证的条款呢?同样,这取决于停车通行证的型号。停车通行证是否允许进入限定的有限车库?然后,自然的解决方案是通行证包含
    车库集合(例如
    集合
    )。但是,停车通行证可能会根据车库的某个属性授予进入车库的权限,例如,车库的位置,或者车库所属的公司。那么,
    集合
    将不代表此停车通行证的条款。即使您能够收集停车通行证条款适用的所有车库(比如,某个位置内的所有车库,只能是有限的一组),收集也不能代表停车通行证的条款,一旦新的车库建成或关闭,这将是相关的。因此,在这种情况下,表示停车通行证条款的更好方法就是使用
    谓词
    。T
    class ParkingPass {
        Collection<Garage> for(Car);
    }