我正在用Java创建一个执行数据移动任务的应用程序(像copy,move等)
在更高级别,我可以在对象级别提供这些操作。
示例代码:
public class DataSource {
public boolean copy(DataSource dsDestination);
public boolean copy(DataSource dsDestination, Filter filter);
public boolean move(DataSource dsDestination);
public boolean exists();
// some other 10-15 methods
}
或者我可以使用静态方法提供实用程序:
public class DataSourceUtil {
public static boolean copy(DataSource dsSource, DataSource dsDestination);
public static boolean copy(DataSource dsSource, DataSource dsDestination, Filter filter);
public static boolean move(DataSource dsSource, DataSource dsDestination);
public static boolean exists(DataSource dsSource);
// some other 10-15 methods
}
哪种方法在内存管理方面更好?
答案 0 :(得分:2)
黄金法则是:静态是良好OO设计中的异常。只有在有充分理由的情况下才能使用它。
您会看到,静态会导致您的班级之间直接耦合。它使测试更加困难。当然,静态方法本身可以很容易地测试,但是如果你想测试一个调用那些静态方法的方法(并且你需要影响静态方法正在做什么)会发生什么?那么你可能会想要转向Powermock以模拟这些静态调用。这不是一个好主意。
如果您坚持分离功能,最好使用接口,例如:
public class DataSource {
... ctor, equals, ... methods
}
public interface DataSourceCopyAbility {
public void copy(DataSource source, DataSource destintion);
加上相应的impl类。
编辑:当然,便利性可能是使用静态方法的正当理由;例如,我一直在代码中使用Objects.requireNonNull()。 但:这些是标准的API调用。当我在我的代码中使用它们时,我真的不介意它们运行。我知道永远不会想要"模拟"围绕这种静态方法调用!
最后:我假设您希望在操作通过后返回 true 。 不好主意:布尔值只应用于区分真假。它们不返回代码!
如果像复制DataSource这样复杂的操作失败 - 那么抛出异常!或者,如果您真的想要没有例外,请定义您自己的特定ReturnCode类,让您深入了解失败的操作!
答案 1 :(得分:2)
忘掉内存管理。
无论您使用哪种方法,您仍然会创建两个{
1 = [
title = "A",
title = "B",
title = "C"
],
2 = [
title = "A",
title = "B"
],
3 = [
title = "D",
title = "E",
title = "F",
title = "G"
]
}
个对象来呼叫function ReplaceInnerHtml(el, type, replaceTo) {
if (el != "" && el != null) {
if (type == "Practitioner") {
el.innerHTML.replace("Practitioner", replaceTo);
} else if (type == "Patient") {
el.innerHTML.replace("Patient", replaceTo);
}
}
}
function SetAllDivLabelCaption(OABPreferences) {
var listlabel = document.getElementsByTagName("label");
var listspan = document.getElementsByTagName("span");
var listdiv = document.getElementsByTagName("div");
for (var i = 0; i < listlabel.length; i++) {
if (listlabel[i].innerHTML.indexOf("Practitioner") > -1) {
ReplaceInnerHtml(document.getElementById(listlabel[i].id), "Practitioner", OABPreferences.OABRenamePractitioner);
} else if (listlabel[i].innerHTML.indexOf("Patient") > -1) {
ReplaceInnerHtml(document.getElementById(listlabel[i].id), "Patient", OABPreferences.OABRenamePatient);
}
}
for (var i = 0; i < listspan.length; i++) {
if (listspan[i].innerHTML.indexOf("Practitioner") > -1) {
ReplaceInnerHtml(document.getElementById(listspan[i].id), "Practitioner", OABPreferences.OABRenamePractitioner);
} else if (listspan[i].innerHTML.indexOf("Patient") > -1) {
ReplaceInnerHtml(document.getElementById(listspan[i].id), "Patient", OABPreferences.OABRenamePatient);
}
}
for (var i = 0; i < listdiv.length; i++) {
if (listdiv[i].innerHTML.indexOf("Practitioner") > -1) {
ReplaceInnerHtml(document.getElementById(listdiv[i].id), "Practitioner", OABPreferences.OABRenamePractitioner);
} else if (listdiv[i].innerHTML.indexOf("Patient") > -1) {
ReplaceInnerHtml(document.getElementById(listdiv[i].id), "Patient", OABPreferences.OABRenamePatient);
}
}
}
或DataSource
。内存使用量差别不大。
你应该关注的是可读性和美学:)。
比较这两个:
copy
第二个更冗长。此外,似乎我们需要一些其他东西(move
)来帮助复制数据。如果我们让数据自己复制(第一个),那么编写代码的代码就会少一些,并且更有意义。
我想指出的另一点是,您可以在第一个中添加someData.copy(otherData);
DataSourceUtils.copy(someData, otherData);
以使其更具可读性:
DataSourceUtils
你不能用第二种方法做到这一点。
答案 2 :(得分:1)
我同意@Jon Skeet,因为所有操作都需要Datasource
自身的源对象,那么它们应该是实例方法。它们类似于equals
类中的Object
。
从可测试的观点来看,实例方法很容易测试。
答案 3 :(得分:0)
这取决于您在这些方法中编写的功能。如果功能未使用任何特定于对象的字段值,则使用静态方法将是正确的选项。
即。确保您使用的变量信息不是特定于对象的,而数据在类级别是通用的
答案 4 :(得分:0)
内存管理的观点,顺便说一下,它们是等价的。这些函数共享它们的编译代码,这些代码存储在只读存储区中。只有这两者之间的差异是this
指针上下文。因此,如果您选择静态或非静态,它不应占用任何空间。大多数编译语言都遵循相同的方式。
答案 5 :(得分:0)
借鉴Apache Commons Lang库和java.lang.Objects
的经验,静态方法的优势在于它们可以提供NullPointerException
在Java代码中看到类似的内容是很常见的:
if (x != null && a.equals(otherX)) ...
或将文字放在左侧的做法:
if ("literal".equals(str)) ...
这些都是NPE保护方式。这是上述自由的原因之一,以及静态方法的情况:
if (ds.copy(dest) == true) ... // may throw NPE
if (DataSourceUtil.copy(ds, dest) == true) ... // NPE protection
答案 6 :(得分:0)
差异:
dataSource.copy();
复制不是我的责任,它是DataSource的责任。
DataSourceUtil.copy();
copy是我的责任,但源代码已编写在实用程序类中以避免重复。