我正在创建一个包含I类的应用程序,名为Person。人物的一个领域是&#39;别名&#39;这是一个ArrayList<String>
。最终,别名将根据以下逻辑显示给用户:如果Person具有别名,则它们应显示为[Finch, Wren, Admin, etc...]
,否则应显示UNKNOWN
。到目前为止,我已经尝试过三种方式之一:
Person包含方法getAliases()
,它只返回ArrayList的副本。调用者检查空数组以实现所需的行为。
Person包含方法aliasesToString()
,可以调用该方法生成所需的字符串。
别名是ArrayList<String>
的实现,而不是DefaultableArrayList<T>
。此类扩展了ArrayList并保存了类型为T的默认值。toString()
方法被覆盖以生成所需的字符串。应用程序调用{{1}}以产生所需的行为。
以下是我对选项3的实现:
some_person.getAliases().toString()
我对选项2和3的关注是,我可能会在违反OOP指南的同时添加不必要的复杂性。如果没有别名,并且别名是否有意义定义它最终如何在应用程序中实现?我认为我应该让调用者处理空案例。我应该选择哪种方案最符合标准OOP设计指南?或者我还没有考虑过第四种选择吗?
答案 0 :(得分:6)
第一个选项是正确选项。模型不应该关注它的显示方式。
在丰富的应用程序,Web应用程序或控制台应用程序中,您不会以相同的方式表示此人和他/她的别名。
即使在给定的应用程序中,您也可能以各种方式表示相同的模型。
如果您将应用程序国际化,则必须将“UNKNOWN”更改为其他内容。
因此,只需按原样返回列表(或列表的不可修改的vew),并让表示层处理表示逻辑。 BTW,toString()
比用于表示应用程序中的对象的函数方法更像是调试帮助。
答案 1 :(得分:3)
让我们来看看你的选择:
Person包含方法getAliases(),它只返回 ArrayList按原样。调用者检查一个空数组来实现 期望的行为。
来电者代码会是什么样子?
if (!person.getAliases().isEmpty()) { //Print aliases }
看起来有点丑陋和难以理解。如果你想使用这个选项,你可以做的最少的是在hasAliases
中添加一个Person
方法,它基本上会对你进行检查并使客户端代码更具可读性:
if (person.hasAliases()) { //Print aliases }
这是更清晰,更易读的代码。
Person包含方法aliasesToString(),可以调用它来生成所需的字符串。
虽然Person
自给自足并不是坏事。客户端代码所要做的就是调用person.aliasesToString()
而不是执行:
if (person.hasAliases()) {
List<String> aliases = person.getAliases();
StringBuilder aliaseString = new StringBuilder("");
for (String alias : aliases) {
aliasString.append(aliases);
}
}
别名是DefaultableArrayList
的实现,而不是使用ArrayList
这对于这么简单的任务来说太过分了。
你选择哪种方法?这取决于您的整体要求。如果您有不同的客户/ UI想要使用别名做不同的事情,选项1将是最好的。如果您有一个客户端总是希望以某种方式打印别名,那么选项2将是更好的选择。
答案 2 :(得分:2)
我发现最简单的方式往往是好风格。也就是说,代码在做一些简单的事情时所获得的丑陋通常意味着风格正在误入歧途。因此,选项1看起来像是实现这一目标的可靠方法。使用getAliases()
返回或打印字段非常标准。此外,您可以实现对空数组的检查,并在该实例中返回或打印UNKNOWN。否则,ArrayList toString()
将负责格式化内容。
答案 3 :(得分:2)
选项3是一种矫枉过正。我不会延长ArrayList
这么小的附加价值。
在选项1和选项2之间进行选择取决于List
返回的getAliases()
是否还有其他预期用途,而不是显示它的字符串表示形式。
我用aliasesToString()
方法看到的唯一缺点是它假设Person类的所有用户都以相同的方式显示别名。
如果你使用getAliases()
方法,我希望该方法返回该List的副本或该List的数组表示。原因是您通过改变getAliases()
返回的List来阻止Person类的用户改变Person实例。