簡體   English   中英

重復刪除此Java代碼重復項

[英]Deduplicate this java code duplication

我有大約10多個類,每個類都有一個LUMP_INDEX和SIZE靜態常量。 我想要每個這些類的數組,其中數組的大小是使用這兩個常量計算的。 目前,我為每個類都有一個函數來創建數組,類似於以下內容:

private Plane[] readPlanes()
{
    int count = header.lumps[Plane.LUMP_INDEX].filelen / Plane.SIZE;
    Plane[] planes = new Plane[count];
    for(int i = 0; i < count; i++)
        planes[i] = new Plane();

    return planes;
}

private Node[] readNodes()
{
    int count = header.lumps[Node.LUMP_INDEX].filelen / Node.SIZE;
    Node[] nodes = new Node[count];
    for(int i = 0; i < count; i++)
        nodes[i] = new Node();

    return nodes;
}

private Leaf[] readLeaves()
{
    int count = header.lumps[Leaf.LUMP_INDEX].filelen / Leaf.SIZE;
    Leaf[] leaves = new Leaf[count];
    for(int i = 0; i < count; i++)
        leaves[i] = new Leaf();

    return leaves;
}

等等。其中有10個函數,唯一的區別是類類型,因此您可以看到,有很多重復項。

是否有人對如何避免這種重復有任何想法? 謝謝。 (我之前問過類似的問題,但我想我問的方式有點不對勁)

使用Java泛型 這樣,您只需編寫一個通用方法並在每次使用時指定類型參數即可。

Bala的解決方案已經接近。 但是,您無法從泛型類型訪問常量,因此我將創建一個getCount()(或任何您想命名的常量),並讓每個子類型都使用適當的常量來實現它。

interface LumpySize<L extends LumpySize> {
    int getCount(); // subtypes return the appropriate header.lumps[Plane.LUMP_INDEX].filelen / Plane.SIZE; 

    T[] initializeArray();

    abstract <T extends LumpySize> static class Base implements LumpySize<T> {
        protected T[] initializeArray(Class<T> cls) {
            int count = getCount();
            T[] lumps = (T[]) Array.newInstance(cls, count);
            for(int i = 0; i < count; i++) {
                try {
                    lumps[i] = cls.newInstance();
                } catch (Exception e) {  // obviously this isn't good practice.
                    throw new RuntimeException(e);
                }
            }
            return lumps;
        }    
    }            
}

class Plane extends LumpySize.Base<Plane> {
    public int getCount() {
        return header.lumps[Plane.LUMP_INDEX].filelen / Plane.SIZE; // assuming header is available somewhere
    }
    public Plane[] initializeArray() { return initializeArray(Plane.class); }
}

Okey doke ...我已經對此進行了測試,以確保能夠滿足您的需求。

您需要一個接口:

public interface MyInterface
{
    public int getSize();
    public int getLumpIndex();
}

您的類實現該接口:

public class Plane implements MyInterface
{

    ...
    public int getSize()
    {
        return SIZE;
    }

    public int getLumpIndex()
    {
        return LUMP_INDEX;
    }

}

header是其實例的類中,您有...

public <E extends MyInterface> E[] 
    getArray(Class<E> c, MyInterface foo)
{
    int count = lumps[foo.getLumpIndex()].filelen / foo.getSize();
    E[] myArray = (E[]) Array.newInstance(c, count);
    for(int i = 0; i < count; i++)
         myArray[i] = c.newInstance();
    return myArray;
}

您可以從飛機類上這樣說:

Plane[] p = header.getArray(Plane.class, this);

覺得呢? :)有人可以看看這個,看看我是否要離開嗎?

編輯:因為我現在已經對其進行了測試-可以工作)

另外需要注意的是,可以通過使getArray()以大小和索引作為參數來消除每個類中的getter:

public <E extends MyInterface> E[] 
    getArray(Class<E> c, int size, int index)
{
    int count = lumps[index].filelen / size;
    E[] myArray = (E[]) Array.newInstance(c, count);
    for(int i = 0; i < count; i++)
         myArray[i] = c.newInstance();
    return myArray;
}

並將其稱為:

Plane p[] = header.getArray(Plane.class, SIZE, LUMP_INDEX);

從班級內部 該接口將變為空以提供泛型類型,而您不必定義getter方法。

(我保證的最后編輯,但這確實為您提供了選擇並解釋了一些有關泛型的信息)

拋開界面。 刪除的內容是一些完整性檢查,因為該方法並不關心您提供給它的對象的類型:

public <E> E[] 
    getArray(Class<E> c, int size, int index)
{
    ...

現在,您不必定義或實現接口,只需調用:

Plane p[] = header.getArray(Plane.class, SIZE, LUMP_INDEX);

使用泛型,但是您需要傳遞某種工廠對象來構造實例以放入集合中,例如:

public class MyClass {

public <E> E[] getArray(IObjectFactory builder, int index, int size){
    ArrayList<E> arrayList = new ArrayList<E>();
    int count = header.lumps[index].filelen / size;//wasn'tsure where header was coming from...
    for(int i = 0; i< count; i++){
        E newInstance = builder.getNewInstance();
        arrayList.add(newInstance);
    }
    return (E[]) arrayList.toArray();
  }   
}    

interface IObjectFactory {
<E> E getNewInstance();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM