使用组合访问对象方法?
Accessing object methods with composition?
这可能是一件非常简单的事情,但我似乎无法独自解决这个问题。使用组合时,访问 "inner object?" 方法的最佳方式是什么?我能想到的每一种方式似乎都违反了某些 OO 原则或其他原则。
这是一个非常宽泛的话题,但我会举一个例子来尽可能清楚地说明问题。代码是用 java 编写的,但我相信这个问题几乎适用于任何使用 OOP 的语言。
Class Shelf {
private Book book;
}
Class Book {
public void turnPage() {
//do stuff
}
}
当您只能访问 Shelf 对象时,访问 Book 方法的最佳方式是什么?我读过的一些地方建议在 Shelf 中使用包装器方法,因为它遵循 Demeter 法则。但是,这似乎并不是每种情况下的最佳选择。
首先,许多内部对象的方法可能与 main class 无关,因此让 main class 为每个方法实现包装器没有任何意义,这很可能会破坏单一职责原则。此外,如果内部对象被用于大量其他 classes 的组合,所有这些都需要做同样的事情,这将导致大量不必要的代码重复,使您的代码更不枯燥。
我的第一直觉是有一个简单的 getBook() 方法,可以访问这本书以直接操作这些方法。把书从书架上拿下来翻页比让书架为你翻书页更有意义。然而,这似乎打破了封装和得墨忒耳法则。如果我要使本书变量 public 最终化,这同样适用。
我错过了什么吗?还是使事情过于复杂?我似乎无法解决这个问题,所以非常感谢您的帮助。
在这种情况下,您很可能只有书,而不是书架上的一本书。对我来说,return 通过书架上唯一的 id 一本特定的书并对其进行操作是非常有意义的。
在那种情况下,我会避免 return 收集会违反封装和 Demeter 法则的书籍。
因此,例如:
public class Shelf {
private Map<Long, Book> books = new HashMap();
// Class Code
public Book getBook(Long id) {
return books.get(id);
}
}
这样的事情不会破坏封装,因为您没有暴露 class 的内部结构。如果您希望使用列表而不是地图,则 class 之外的任何地方都不会受到更改的影响。
而且,在这种情况下,return 这本书比在 Shelf
class 中创建方法 turnPage()
更有意义。这与 属性 name
in Book
中的字符串类型相同。您不会在 Book
中创建方法 nameSubstring()
只是为了对 name
进行操作,对吗?那么为什么要在 shelf 中创建一个 turnPage()
只是为了对 Book
进行操作?
这可能是一件非常简单的事情,但我似乎无法独自解决这个问题。使用组合时,访问 "inner object?" 方法的最佳方式是什么?我能想到的每一种方式似乎都违反了某些 OO 原则或其他原则。
这是一个非常宽泛的话题,但我会举一个例子来尽可能清楚地说明问题。代码是用 java 编写的,但我相信这个问题几乎适用于任何使用 OOP 的语言。
Class Shelf {
private Book book;
}
Class Book {
public void turnPage() {
//do stuff
}
}
当您只能访问 Shelf 对象时,访问 Book 方法的最佳方式是什么?我读过的一些地方建议在 Shelf 中使用包装器方法,因为它遵循 Demeter 法则。但是,这似乎并不是每种情况下的最佳选择。
首先,许多内部对象的方法可能与 main class 无关,因此让 main class 为每个方法实现包装器没有任何意义,这很可能会破坏单一职责原则。此外,如果内部对象被用于大量其他 classes 的组合,所有这些都需要做同样的事情,这将导致大量不必要的代码重复,使您的代码更不枯燥。
我的第一直觉是有一个简单的 getBook() 方法,可以访问这本书以直接操作这些方法。把书从书架上拿下来翻页比让书架为你翻书页更有意义。然而,这似乎打破了封装和得墨忒耳法则。如果我要使本书变量 public 最终化,这同样适用。
我错过了什么吗?还是使事情过于复杂?我似乎无法解决这个问题,所以非常感谢您的帮助。
在这种情况下,您很可能只有书,而不是书架上的一本书。对我来说,return 通过书架上唯一的 id 一本特定的书并对其进行操作是非常有意义的。
在那种情况下,我会避免 return 收集会违反封装和 Demeter 法则的书籍。
因此,例如:
public class Shelf {
private Map<Long, Book> books = new HashMap();
// Class Code
public Book getBook(Long id) {
return books.get(id);
}
}
这样的事情不会破坏封装,因为您没有暴露 class 的内部结构。如果您希望使用列表而不是地图,则 class 之外的任何地方都不会受到更改的影响。
而且,在这种情况下,return 这本书比在 Shelf
class 中创建方法 turnPage()
更有意义。这与 属性 name
in Book
中的字符串类型相同。您不会在 Book
中创建方法 nameSubstring()
只是为了对 name
进行操作,对吗?那么为什么要在 shelf 中创建一个 turnPage()
只是为了对 Book
进行操作?