【问题标题】:Reference another class using an index vs storing entire instance使用索引引用另一个类与存储整个实例
【发布时间】:2018-09-23 22:49:18
【问题描述】:

在一个需要“包含”关于另一个类的信息的类中(对不起,我不知道这个术语),我应该将对该其他类的引用存储为整数/id 之类的东西,还是应该存储它作为另一个类的实例?如果有名字,这叫什么?

作为一个非常基本的示例,我们要在其中存储用户最喜欢的餐厅的应用:

public class User {
    public int id { get; set; }
    public string name { get; set; }

    // id of restaurant...
    // public int favoriteRestaurantId { get; set; }

    // ...or entire instance of Restaurant type
    // public Restaurant favoriteRestaurant { get; set; }
}

public class Restaurant {
    public int id { get; set; }
    public string name { get; set; }
}

注意:如果您认为这是题外话,请解释为什么这个问题会被允许并且是一个高度评价/有用的问题,但我的不是:Interface vs Base class 或者至少告诉我这是什么“叫“所以我可以自己研究更多。据我从 Stackoverflow 的常见问题解答中可以看出,这个问题是主题。

【问题讨论】:

  • 在 OOP 中,您使对象直接引用其他对象,而不是它们的 ID 或名称。因此,如果user 有一个最喜欢的restaurant,则user 应该将restaurant 实例存储为其属性之一(实例变量),而不是餐厅的名称或ID。
  • 一个对象包含对另一个对象的引用称为对象组合。请参阅:stackoverflow.com/questions/3441090/…。这可能是 OOP 中最重要的原则。
  • 你的问题被标记为oop,但你问“我应该吗?”存储对其他对象的引用更加“面向对象”,但是您是否应该取决于许多其他因素。在面向数据的编程中,存储 ID(以及具有对更高级别数据结构进行操作的函数)更为常见。
  • 参见,例如,What is data oriented design? 我认为您的问题归结为“我应该选择什么范式?”这最终取决于您。

标签: oop language-agnostic


【解决方案1】:

你的第一个变种

public int favoriteRestaurantId { get; set; }

仅当您只对 id 感兴趣而不对 restaurant 对象的其他属性 (name) 感兴趣时才有意义。否则,您将需要一些外部容器来存储所有 restaurant 对象,并且必须使用给定的 id 在容器中搜索 restaurant

在您的第二个变体中

public Restaurant favoriteRestaurant { get; set; }

如果你写

someUser.favouriteRestaurant = someRestaurant;

这还存储了对现有someRestaurant 的引用。它不会复制整个对象。至少在 C# 和 Java 等语言中不会。

只有当你做类似的事情时

someUser.favouriteRestaurant = new Restaurant(someRestaurant);

user 将拥有自己的 restaurant 对象副本。

在某些情况下这是有道理的,但在您的示例中,这可能不是一个好主意,原因有两个:

  1. 如果例如someRestaurantname 发生变化,这也应该更改favouriteRestaurant 的名称。如果favouriteRestaurant 是副本,这不会自动发生。

  2. 这是浪费内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 2015-05-13
    • 2019-12-05
    • 1970-01-01
    相关资源
    最近更新 更多