2012-08-15 67 views
3

我有一個代碼重複的情況(或是否?),我不知道如何避免它,但仍然保持清晰的代碼。代碼重複(或不) - JAVA

讓我巨大的過於簡單化的情況:

// let's say I have a interface Entity 

interface Entity { 

    public Entity add (Entity operand); 

} 

// And two classes that implement this interface 

class MyInteger implements Entity { 

    private int value; 

    public Entity add (Entity operand) 
    { 
     // here I have to manage the situation distinctly if operand is a MyInteger or MyString 

    } 

} 

class MyString implements Entity { 

    private String value; 

    public Entity add (Entity operand) 
    { 

    } 
} 

現在,我的問題是,該方法MyString中添加是bassicly一樣的方法加入MyInteger。請記住,我有比這裏提到的兩種類型更多的類型,並且對於某些方法add來說是不一樣的。

此代碼是否重複?如果是這樣,有沒有辦法避免它?因爲我似乎無法想到一個。

另外,在add方法中,如何在不使用if(instanceof)語句的情況下在各種類型操作數之間切換?

+2

您是否聽說過仿製藥? – SiB 2012-08-15 08:59:20

回答

1

查找模板模式。您可以重構併爲任何重複的代碼添加一個Abstract類。如果這是特定於兩個類的,那麼您可以讓這兩個類擴展Abstract類。

爲了避免instanceof我不確定什麼是最好的,但是你可以鏈接一個特定於實體類的額外方法,然後在必要時調用超類/抽象類。最後,調查泛型提供了什麼樣的可能性。

1

聽起來像你需要visitordouble-dispatch機制。

add(Entity operand)方法決定基於傳遞操作數做什麼,所以你可以通過調用操作數回實現這一目標。例如

// in MyInteger 
public Entity add(Entity operand) { 
    operand.addInteger(this); 
} 

// in MyString 
public Entity add(Entity operand) { 
    operand.addString(this); 
} 

請注意,上述更改的實現類型稱爲。通過重定向回操作數,您的呼叫路徑由最初使用的操作數所確定。

每個實體將不得不實施addInteger(MyInteger p),addString(MyString p)等,但在這個階段你有具體的類型來處理,可以平凡地確定做什麼。

請注意,您不必使用instanceof或類似的。以上是類型安全且完整的。例如添加新的操作數類型將導致一組顯着的重構。

+0

這是一個乾淨的回調方式。但我不清楚這是如何取代'instanceof'的。糾正我,如果我錯了,但這裏的想法是讓一個實體類型處理特定? – 2012-08-15 09:19:32

+1

如果添加MyDouble,則會在操作符上調用addDouble。每個操作人員都必須決定如何向自己添加雙倍(不是不合理的) – 2012-08-15 09:22:32

+0

我不認爲這有幫助。實體是一個接口,因此您不能將addInteger/addString作爲方法調用,直到它在實體中實現。正如其他答案所說的那樣,您需要一個抽象超類或實用方法。 – 2012-08-15 10:44:49

1

您可以使用抽象類併爲其提供具體的添加方法。

+0

我不確定我關注。沒有具體的添加方法。結果根據操作數的不同而不同。說我添加兩個MyInteger,我的結果也是一個MyInteger,但如果我添加一個MyInteger到一個MyString,結果是一個MyString。你能給我一個你是什麼意思的代碼示例嗎? – user1550876 2012-08-15 11:10:44

1

到目前爲止,我在您的方法中看不到問題。

由於實體是一個實例,你可以解決重複代碼:

  • 根本無視它,做重複的,因爲它會給你一個乾淨的解決方案。 如果您只有少數情況下發生此類重複,可能會更好地以這種方式實施它。

  • 如前所述,實現一個抽象類,例如AbstractEntity一次將所有 方法實現爲受保護的成員方法,並將MyInteger和MyString聲明爲子類。

  • 請繼續進行子類化,考慮需要哪些方法來爲哪個實體和 構建一個子類樹。小心:如果你不能仔細設計,這將妨礙進一步的調整。

  • 使用實用類:具有公共靜態方法的類和具有 的私有構造函數實現需要的功能。

如何找出實體類型:

  • 使用的instanceof(好吧,這是醜陋的)
  • 實現該接口的返回或屬性類型枚舉測試 方法: getType()== STRING或isString()
  • 在接口中實現您希望執行的方法:checkIfStringAndAddIt()。