我需要为java中的对象子集创建一个唯一的名称。基本上我有一个显示对象和它的多个实例。显示的每个实例都需要具有唯一的名称以用于审计目的。当您查看审核时,您将知道审核的显示内容。我正在寻找的是如何将此作为可能使用设计模式的最佳实践。以下是我目前的一些想法
IDEA 1 使用toString()每个对象已经有一个toString,所以覆盖它应该提供一种简单的方法来命名对象。这方面的缺点是所有对象都有一个toString,因此很难强制显示对象已填写,而其他所有对象都不需要它。
IDEA 2 使用界面。我可以使用名为getName()的函数创建一个名为IDisplayName的接口。我的Display对象可以实现这个接口,所以我的具体分类需要设置它。这就是我目前实施的目标。
IDEA 3 与IDEA 2相同但getName()返回ENUM而不是String。这样我可以在单个文件中强制执行唯一性,并且ENUM将具有displayString属性。这个问题是有很多所说的显示对象> 100,所以这可以非常快。
IDEA 4 只需记录类名。这不能很好地工作,因为程序员不会阅读审计,因此我更愿意使审计更加友好。
提前感谢您的帮助。
答案 0 :(得分:1)
我的观点是你应该使用一个界面。当然,为了这个目的,可以重用toString
或类名,但显然是以未来读者不清楚的方式重载它们的使用。例如,如果将来的重构拆分类,审计跟踪将以未定义的方式更改。同样,toString
实施可能会因多种原因而发生变化。
而不是调用您的界面IDisplayName
,我建议将其称为Auditable
或类似,以使其目的显而易见。理想情况下,您的审计方法将采用Auditable
。
interface Auditable {
public String getAuditName();
}
答案 1 :(得分:1)
我不会使用toString,因为它可能有其他用途(如调试)或打印对象状态。如果非程序员不清楚返回类名,那么程序员可能也不清楚。我的意思是,如果您使用清洁代码的原则,您的班级名称应该对每个人都清楚。然后,您必须通过仅显示简化的类名来删除包:String simplifiedClassName = qualifiedClassName.substring(qualifiedClassName.lastIndexOf(".") + 1).
如果您想要更灵活,可以像这样定义IDisplayName.getName
:
default String getName() {
String qualifiedName = getClass().toString();
return qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
}
这是一个界面默认方法,这意味着程序员只能在他们认为必须的类中覆盖它。
另一种可能性,如果您需要国际化/本地化:
您的getName
可以从属性文件中读取该属性
key是简化的类名。属性文件可以由非程序员编辑,具有100个条目的属性文件不是很大。在属性文件中保证值的唯一性也很容易。
编辑Java 7:除IDisplayName
接口外,创建一个名为DisplayNameUtil
的类,其中getName
是静态方法:
public static String getName(Object obj) {
String qualifiedName = obj.getClass().toString();
return qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
}
然后,在您的大多数显示类(或常见的超类)中,您可以添加以下内容:
@Override
public String getName() {
return DisplayNameUtil.getName(this);
}
程序员仍然可以返回所选类的特定名称,
如果需要,接口getName
仍然可以访问属性文件。
具有为接口方法提供默认行为的Util类是 Java 7模式。顺便说一句,建议删除伴随的Util类 从Java 7迁移到8时的重构。换句话说,如果您的代码曾经 转换为Java 8,很容易重构它以使用默认值 接口中的方法并删除Util类。
答案 2 :(得分:0)
如果类只需要是唯一的,那么我只需要将您的显示对象的每个实例与某个ID相关联,这就是我要做的: 在您的Display类中,您应该有一个静态常量,并且应为每个显示实例分配一个ID。该ID将是当时Display中常量的值。然后,一旦分配了id值,就会增加常量的值。然后,为Display类提供一个getId()方法,该方法允许您在所有子类上调用它,并为每个实例获取唯一标识符。
public class Display(){
private static int idCounter = 0;
private final int id;
public Display(){
id = idCounter++;
}
public int getId(){
return id;
}
}
现在,每个Display实例(包括子类)都将拥有这个唯一的ID,您可以调用它来识别它。