2015-01-26 54 views
2

我需要爲java中的對象的子集有唯一的名稱。基本上我有一個顯示對象和它的多個實例。爲了審計目的,每個顯示實例都需要具有唯一的名稱。這是如此,當你看審計時,你會知道什麼顯示被審計。我正在尋找的是如何使用設計模式將其作爲最佳做法。以下是我目前的一些想法在java中命名對象的最佳實踐

IDEA 1 使用toString()每個對象都有一個toString,所以重寫這個應該提供一個簡單的方法來命名對象。對此的缺點是所有對象都有一個toString,所以很難強制Display對象填充它們,而其他所有對象都不需要它們。

IDEA 2 使用接口。我可以用名爲getName()的函數創建一個名爲IDisplayName的接口。我的顯示對象可以實現這個接口,所以我的具體分類將需要設置它。這是我目前實施的。

IDEA 3 與IDEA 2相同,但getName()返回的是ENUM而不是String。這樣我可以在單個文件中強制執行唯一性,並且ENUM將具有displayString屬性。問題在於有很多顯示對象> 100,所以這可以變得非常快。

IDEA 4 只需記錄類名。由於審計不被程序員讀取,所以我不希望使審計更友好。

在此先感謝您的幫助。

+0

Just * make *類名用戶友好,例如通過省略包裝部分。 – EJP 2015-01-26 22:38:42

+0

您能否詳細說明您的意思是「多顯示器擴展它」?他們是「顯示」(或其他類)對象,並且每個顯示都是一個實例?還是不同的顯示大師班的一些子類? – ahjohnston25 2015-01-26 23:07:03

+0

顯示對象,每個顯示是一個實例 – 2015-01-26 23:27:50

回答

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可以讀取屬性文件的名稱,其屬性 關鍵是簡化的類名。屬性文件可以由非程序員編輯,而具有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模式。順便說一下,當從Java 7移動到8時,建議移除伴隨Util類的 重構。換句話說,如果您的代碼 被翻譯爲Java 8,則很容易將其重構爲在界面中使用默認的 方法並刪除Util類。

+0

這是Java 8+ – Dave 2015-01-27 00:05:40

+0

這將工作的很好,但可悲的是我使用Java 7.除了默認情況下,我認爲這將工作得很好。也許如果我升級到8,那麼我可以實現一個默認值。 – 2015-01-27 00:24:41

+0

@JaredSol查看我對Java 7的編輯。只需稍後升級即可。你可以添加評論做接口,向未來的程序員解釋如何升級,或者簡單地添加一個鏈接到這個頁面。 – MarcG 2015-01-27 00:26:04

1

我認爲你應該使用一個接口。雖然當然可以重用toString或爲此目的使用類名,但它顯然會以未來讀者不清楚的方式超載它們的使用。例如,如果將來的重構拆分類,審計線索將以未定義的方式變化。同樣的toString實現可能會因多種原因而改變。

而不是調用您的接口IDisplayName我建議將其稱爲Auditable或類似的,以使其目的明顯。理想情況下,您的審計方法將採取Auditable

interface Auditable { 
    public String getAuditName(); 
} 
0

如果類只需要是唯一的,那麼我只想有一些ID相關聯的顯示對象的每個實例,這是我會怎麼做: 在你的顯示器類,你應該有一個靜態常量和每個顯示實例都應該分配一個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; 
    } 
} 

現在,每個顯示實例(包括子類)都將具有此唯一ID,您可以調用該ID來識別它。

+0

這不會強制每個顯示器總是一次又一次地獲得相同的id時間,如果它們的創建順序改變正確的話? – 2015-01-27 00:09:59

+0

正確。對不起,我沒有意識到這是一個要求。 – 2015-01-27 00:29:26