【问题标题】:Should I use a Map<String,String> instead of a class for creating a flexible object?我应该使用 Map<String,String> 而不是类来创建灵活的对象吗?
【发布时间】:2018-03-18 14:41:33
【问题描述】:
public class Person
{
    protected Map<String, String> data;

    public String getString(String key)
    {
        return getData().get(key);
    }

    public void setString(String key, String val)
    {
        getData().put(key, val);
    }
}

我想要一个灵活的对象,它可以改变并最终拥有新的字段,或者根据用户的需要,字段最终会被闲置。

首先说用户只需要基本字段:姓名、年龄、身高。

但稍后另一个用户需要在已使用的字段之上捕获:头发颜色、眼睛颜色和种族

使用字符串,字符串映射是否可行?

我可以创建所有字段

int age;
int height;
String name;
String eyeColor;
...

但我的“Person”只能通过这些字段扩展到目前为止。不确定最佳实践是什么,或者字符串映射是否是路线。任何见解将不胜感激。

这个项目是一个用于保险目的的 crud 应用程序。每个分公司以不同的方式存储驱动程序并以不同的方式使用驱动程序信息,因为哪些数据字段被捕获,哪些未被捕获。有些人记录了某人发生了多少事故,有些则没有。有些需要多年驾驶和驾驶员等级,而有些则不需要。我不确定制作灵活对象的最佳设计实践,该对象扩展到每个分公司的案例,而不创建多个驱动程序扩展对象,因为每次新运营商进来时,我都需要一个新对象来满足他们的需求

使用:

Java JSP/Struts2 MySQL 作为数据库。

【问题讨论】:

  • 如果您知道您的键始终是字符串(即“姓名”、“身高”、“年龄”等),您也许可以使用 。它会使它变得更通用,并且您始终可以以不同的方式解析对象。这个问题有更多的背景吗?如果我们知道 Person 的用途以及如何/何时在程序中添加字段,我们可能会给您更多的见解。
  • 如果你反对强类型,你确定要使用Java吗?切换语言可能比绕过基本语言设计更容易。
  • 它是动态的,但与普通字段相比,性能较重。我会确保您不能使用其他用户可以扩展的基类或装饰器模式,然后再退回到您提出的解决方案。
  • 您将需要更具体,有时可以。您实际上想解决什么设计问题?
  • @Oleg 该项目是一个用于保险目的的 crud 应用程序。每个分公司以不同的方式存储驱动程序并以不同的方式使用驱动程序信息,因为哪些数据字段被捕获,哪些未被捕获。有些人记录了某人发生了多少事故,有些则没有。有些需要多年驾驶和驾驶员等级,而有些则不需要。我不确定制作灵活对象的最佳设计实践,该对象扩展到每个分公司的案例,而不创建多个驱动程序扩展对象,因为每次新运营商进来时,我都需要一个新对象来满足他们的需求跨度>

标签: java oop


【解决方案1】:

您可能正在犯一个非常常见的错误,尽管在少数情况下您可能是正确的。

您认为创建一个新类会增加应用程序的复杂性和开销,避免创建一个会使其更简单。情况可能并非如此,而且很可能会适得其反。类的存在是为了让生活更轻松:这就是它们被发明的原因。

如果您需要为每个分公司添加的这些字段要求您编写使用它们的逻辑,那么您将不得不从地图中提取这些字段并将它们放入变量中,然后编写一些逻辑来操作他们。由于您没有课程,因此您将无法封装该逻辑(如果这样做有意义的话)。您将无法键入该字段(是数字、字符串还是布尔值)。除了显式检查之外,您将无法知道 Map 是否包含该字段。您将无法轻松查看它是什么类型的地图。你将不得不转换一切。

例如,假设您需要在类中为分支添加“年龄”字段。在 Java 中,您为该分支创建一个类,添加一个 int 字段,然后为其编写逻辑。您还可以使用各种 OO 技术来处理类似的类(例如,使用 getAge() 方法创建接口)。

此外,不要假设扩展类始终是添加额外数据的正确方法。有时,拥有一个或多个带有关联数据的附加类是一种更好的方法。

在 Map 语言中,您获取 String,检查它是否存在(可能为 null)将其转换为 int,处理可能的解析异常。所有这些逻辑都必须在某些实用程序类或某种助手中浮动。它看起来很糟糕,无论如何你都有你的临时 int ,而且你最终可能会得到一个分支逻辑的助手,无论如何它都是一个类。

您的地图可能适用的情况是您只是在屏幕上显示属性而不做任何逻辑。在这种情况下,最简单的方法可能是使用名称-值对(您正在做的事情的通用模式)并编写一些可以显示任何内容的通用逻辑。

另一个影响您选择的因素是对象是否使用某种 Hibernate 类型的东西进行持久化。如果是这种情况,那么拥有多个类往往会导致更多的数据库表(尽管可以避免)。这可能是好是坏。这对 DBA 来说会更复杂,但另一方面,如果分支特定数据位于适当的表中而不是某些 NVP 结构中,则查看和搜索分支特定数据会容易得多。

总而言之:不要假设具有更多类的解决方案会更复杂。

【讨论】:

  • 感谢您抽出宝贵的时间来写这篇文章。目前,所有虚假逻辑都是应用程序所做的,无论您在 toString()、integer.parseInt()... 之间切换,然后返回字符串来设置地图。它很麻烦而且非常丑陋。我正在和我的老板讨论为什么我们使用 Map 来处理他经常说的灵活性。另一个原因是将 JSP 页面中的参数作为字符串读取,以这种方式存储数据更容易,但我不这么认为,我正在寻找关于哪种方法实际上是首选和性能方法的指导。
  • 我以前见过这个。它可能是正确的,但这种反模式通常来自“懒惰的建筑师综合症”。架构师指定一个地图并列出 Word 文档中的字段以及伪类的表格,并将其称为“接口”。您现在基本上是在 Word 中编程。这对架构师来说很容易——他们不需要设计任何软件,不需要编译,不需要语法检查,不需要运行,不需要通过任何测试。程序员最终整理出实现混乱,这需要做所有这些事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
  • 2014-09-02
相关资源
最近更新 更多