简体   繁体   English

在Java中将对象从一个位置移动到另一个位置

[英]Moving Objects from location to location in Java

This is something I found difficult to research as it requires some explanation. 我发现这很难研究,因为需要一些解释。

I basically want to understand the best way of moving objects around other objects and keep track of where everything is. 我基本上想了解在其他物体周围移动物体的最佳方法,并跟踪所有物体的位置。 Allow me to explain.. 请允许我解释一下。

Let's pretend we are making a Person class and a Park class. 假设我们正在制作一个Person类和一个Park类。 The park class has a bunch of toys and rides for the person to play on.. These could be a Slide class, SeeSaw class, ect.. But lets say our program needs to keep track of where the Person object is at all times. 公园课上有一堆玩具和供人玩的游乐设施。这些可以是Slide类,SeeSaw类等。但是可以说,我们的程序需要始终跟踪Pe​​rson对象的位置。 If they are on the slide, we will want to ask the person class their location. 如果他们在幻灯片上,我们将要询问课程的人他们的位置。 For example... 例如...

//location could be set in the person whenever we move them..
person.setLocation(slide);
//now getLocation could return the object they are on (slide, seesaw, ect)
person.getLocation(); 

But now lets say I'd like to figure out who is on the Slide object that is in the Park at any given time. 但是,现在让我说出我想找出谁在任何给定时间在公园中的Slide对象上。 It would be something like ... 就像...

slide.getOccupants(); // could return the objects that are on the slide (Persons)

But now that means that when the Person moves from object to object in the Park. 但是现在这意味着当人在公园中从一个物体移到另一个物体时。 I'd have to say something like... 我不得不说类似...

person.setLocation(seeSaw);
slide.removeOccupant(person);
seeSaw.addOccupant(person);
//this would get annoying and scary to do everytime a person moves...

So would creating a method to handle all of these changes be the way to go? 那么,创建一种方法来处理所有这些更改是否就可以解决? For example every time a person moves, it could call this code... 例如,一个人每次移动时,都可以调用此代码...

//person being who you're moving and the ride being where you're moving them to..
public void move(Person person, Ride ride){
    person.getLocation().removeOccupant(person);
    person.setLocation(ride);
    person.getLocation().addOccupant(person);
}

I can't help but feel there's a better way to do this as it feels to get messy on larger scale. 我忍不住觉得有一种更好的方法可以做到,因为它感觉到更大规模了。 Perhaps I am overthinking it but I'd love to know of any best practices or designs when it comes to this. 也许我想得太多了,但是我很想知道有关此的任何最佳实践或设计。

Thanks. 谢谢。

According to the Functional Programming folks, you hit a real problem of OO. 根据函数编程人员的说法,您遇到了一个真正的OO问题。 As a purely OO driven world does not allow you to represent this problem in consistent ways. 由于纯粹是面向对象的世界, 因此您无法以一致的方式来表示此问题。 No matter how you do it, you end up with one of three possibilities: 不管您如何执行,最终都会有以下三种可能性之一:

  • person X is nowhere X人不在
  • person X is in two locations X人在两个地方
  • you don't know where person X is 你不知道X人在哪里

So the real problem here is that you have multiple objects, and moving locations changes the overall system state. 因此,这里的真正问题是您有多个对象,并且移动位置会更改整个系统状态。 All fine without threads, but as soon as you have multiple threads kicking in, different threads might see inconsistent states. 没有线程,一切都很好,但是一旦有多个线程加入,不同的线程可能会看到不一致的状态。

The FP folks thus tell you that you first of all need to address that conceptual problem, by having a function that "moves" the system from one valid state into another valid state. FP人员因此告诉您,您首先需要通过具有将系统从一个有效状态“移动”到另一有效状态的功能来解决该概念性问题。 Very much like your move() code, but without inconsistently updating "object states" whilst being in that method. 非常类似于您的move()代码,但是在使用该方法时不会不一致地更新“对象状态”。

OK, but that is probably not what you are asking for. 好的,但这可能不是您要的。 One answer to your problem is: think of moving a person as a service . 您的问题的一个答案是:考虑一个人作为服务 You have entities (people, locations), and that service is responsible for "moving" things around. 您拥有实体 (人员,位置),并且该服务负责“移动”事物。

And guess what: then your first implementation is a good start. 想一想:那么您的第一个实现就是一个好的开始。 So, actually, for an "educational" project, you are doing fine. 因此,实际上,对于“教育”项目,您做的很好。 Probably you should think about decent interfaces to use (to abstract the details of the "things" that get moved, or the places they move from/to). 可能您应该考虑使用合适的接口(以抽象出要移动的“事物”的详细信息,或它们从/移至的位置)。 Put that into a specific service class, and work from there. 将其放入特定的服务类,然后从那里开始工作。

To maintain the history and current information about who is and was at a Location , you don't have thousand of choices : you have to save them somewhere. 要维护有关某个Location人的历史和当前信息,您没有成千上万的选择:您必须将它们保存在某个地方。
Your sample code shows a way to do that. 您的示例代码显示了一种实现方法。
Another way would be to use AOP by applying an Aspect that updates the state at each time a person moves somewhere. 另一种方法是通过应用一个Aspect来使用AOP,该Aspect在一个人每次移动到某个地方时都会更新状态。
But if you did that to spare 3 or 4 invocations, it seems overkill. 但是,如果您这样做是为了省去3或4个调用,那么这似乎太过分了。

About the actual code, you can factor this processings with a method that accepts any Location to be more generic such as : 关于实际代码,您可以使用一种接受任何Location的方法来将此处理分解为更通用的方法,例如:

public void move(Person person, Location newLocation){  
    person.getLocation().removeOccupant(person);
    person.setLocation(newLocation);
    person.getLocation().addOccupant(person);
}

In this way, it is much more straight for the client code. 这样,对于客户端代码而言,它变得更加直接。

As a side note, a Location instance should probably not be responsible to set itself the set of any Location . 附带说明一下, Location实例可能不应该负责为自己设置任何Location的集合。 It gives to it too much responsibilities. 它给它带来了太多的责任。
You could separate the concerns by delegating the processing to a Locations class responsible of the state change. 您可以通过将处理委托给负责状态更改的Locations类来分离问题。

One possible solution is to, instead of constructing a whole new move method which creates the feeling of excessive code, allow the setLocation method for the person to essentially use the same code as the move method you constructed (remove the person from the current park toy and move them to another) . 一种可能的解决方案是,与其构造一个全新的move方法(而不是创建过多代码的感觉),而是让此人的setLocation方法本质上使用与您构造的move方法相同的代码(将该人从当前的玩具中移除)并将其移至另一个)。 This will allow for cleaner code, and should keep all functionality the same. 这将允许使用更简洁的代码,并且应保持所有功能相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM