【问题标题】:Java : Duplication of methodsJava:方法的重复
【发布时间】:2014-10-16 21:05:39
【问题描述】:

这感觉像是一个基本的问题,但这对我来说是全新的:

我有一个 Person 和 Room 类,它们都有一个 Item 对象列表。

public class Person{
  private ArrayList<Item> items;

  public Person() {
    items = new ArrayList<>();
  }

  public void addItem(){
  ...
  }

  public void removeItem(){
  ...
  }

}    

public class Room {

  private ArrayList<Item> items;

  public Room () {
    items = new ArrayList<>();
  }

  public void addItem(){
  ...
  }

  public void removeItem(){
  ...
  }

}

项目方法,例如addItem() 在 Room 类和 Person 类中都是重复的,这不是很好。我考虑过创建一个单独的 Inventory 类,其中包含项目列表和项目方法,然后每个房间和每个人都会有一个库存。

但是,如果我使用私有 Inventory 字段,我将无法从 Person 或 Room 调用 Item 方法。

在此处停止重复的最佳方法是什么?提前致谢!

【问题讨论】:

  • 您可以在 Person 和 Room 类中创建适当的方法来委托给库存对象。
  • 您的解决方案似乎是正确的方法。我会说您尝试实现聚合设计模式。也许这些想法会有所帮助:commons.oreilly.com/wiki/index.php/…

标签: java class oop


【解决方案1】:

你是对的。制作一个单独的清单类将是一个很好的 OOP 设计。

我很高兴您没有说为 RoomPerson 创建父类,因为虽然这样可以避免重复,但 Room 和 Person 不相关,因此它们不应该在面向对象的感觉。

您可以使用委托将添加/删除项目委托给您的 Inventory 字段。

public class Room {

    private Inventory inventory = new Inventory();

    public void addItem(Item item) {
        inventory.addItem(item);
    }

    public void removeItem(Item item) {
        inventory.removeItem(item);
    }
}

编辑

有些人提议公开 Inventory,然后在 person.getInventory().addItem(item) 上使用公共的添加/删除方法。我认为这会违反Law of Demeter

【讨论】:

  • +1。关于您的“编辑”:我认为这是否违反取决于实际域。 “给我你的库存,让我在其中添加/删除项目”在某些领域可能是语义上正确的操作,而在其他领域则不是。对于初学者,一个很好的测试可能是问:Person Inventory 还是只是在内部使用一个?
  • 谢谢!我想过这样做,但想知道是否还有其他方法。但现在我认为你的方式可能是最好的。
【解决方案2】:

我认为库存类是最好的方法。你可以通过在PersonRoom中为库存创建一个getter来使用item方法。

【讨论】:

  • 这对我来说似乎不是一个好的解决方案。以这种方式使用吸气剂是个好主意吗?
  • 您可以按照其他人的建议使用委托方法,但我认为使用 getter 进行库存没有问题。库存类将有一个私有的ArrayList 和用于添加和删除项目的公共方法。
  • 通过不使用 getter 并委托给 Person 或 Room 类,您可以更好地封装,因为您不会向调用者透露项目如何存储的细节。
  • 委托给PersonRoom 类会隐藏哪些细节无法在库存类中隐藏?
  • Person 或 Room 使用 Inventory 来存储物品的事实。调用者不应该关心项目是如何存储的。
【解决方案3】:

根据您的业务领域,您也可以有一个抽象的存储容器类,它们都继承自。抽象存储容器上会有方法,所以你仍然可以直接调用它们。

你也可以给两个类一个空的 IStorageContainer 接口,然后用一个静态方法创建一个新的静态类,该静态方法接受 IStorageContainer 的第一个参数。

然后您可以调用 AddItem(thisPerson, item) 和 RemoveItem(thisPerson, item) 但可以使用相同的代码和实现为两个类重用这两个方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2014-10-17
    • 2011-07-07
    相关资源
    最近更新 更多