- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这可能是一件非常简单的事情,但我似乎无法独自解决这个问题。使用组合时,访问“内部对象”方法的最佳方式是什么?我能解决的每一种方法似乎都违反了某些 OO 原则或其他原则。
这是一个非常宽泛的话题,但我会举一个例子来尽可能地说明问题。代码是用 java 编写的,但我相信这个问题几乎适用于任何使用 OOP 的语言。
Class Shelf {
private Book book;
}
Class Book {
public void turnPage() {
//do stuff
}
}
当您只能访问 Shelf 对象时,访问 Book 方法的最佳方式是什么?我读过的一些地方建议在 Shelf 中使用包装器方法,因为它遵循 Demeter 法则。但是,这似乎并不是每种情况下的最佳选择。
首先,许多内部对象的方法可能与主类无关,因此让主类为每个方法实现包装器没有任何意义,而且很可能会破坏单一职责原则。此外,如果内部对象被用于大量其他类的组合,所有这些类都需要做同样的事情,这将导致大量不必要的代码重复,使您的代码不那么干。
我的第一直觉是要有一个简单的 getBook() 方法,以提供对书的访问权限以直接操作这些方法。把书从书架上拿下来翻页比让书架为你翻书页更有意义。然而,这似乎打破了封装和得墨忒耳法则。如果我要将 book 变量设置为 public final,这同样适用。
我错过了什么吗?还是使事情过于复杂?我似乎无法解决这个问题,所以非常感谢您的帮助。
最佳答案
在这种情况下,您很可能只有书,而不是书架上的一本书。对我来说,通过书架上唯一的 id 归还一本特定的书并对其进行操作是非常有意义的。
在那种情况下,我会避免退回会违反封装和 Demeter 法则的藏书。
所以,例如:
public class Shelf {
private Map<Long, Book> books = new HashMap();
// Class Code
public Book getBook(Long id) {
return books.get(id);
}
}
这样的事情不会破坏封装,因为您没有公开类的内部结构。如果您希望使用列表而不是 map ,则类之外的任何地方都不应受到更改的影响。
而且,在这种情况下,归还书籍比在 Shelf
类中创建方法 turnPage()
更有意义。这就像您在 Book
中有一个字符串类型的属性 name
一样。您不会在 Book
中创建方法 nameSubstring()
只是为了对 name
进行操作,对吧?那么为什么要在 shelf 中创建一个 turnPage()
只是为了对 Book
进行操作?
关于oop - 使用组合访问对象方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33460554/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!