簡體   English   中英

在構造函數中傳遞參數的最佳方法

[英]Best way to pass arguments in constructor

我有一個在表布局中創建行的類。 行的創建取決於數據和元數據。 由於每行的元數據都是相同的,例如顯示/隱藏可見性屬性等,因此我將元數據屬性創建為靜態文件,並使用initWidgetRowWidget初始化。

只是一個例子:

class RowWidget extends FlexTable{

  public static void initWidget(Form form,
    HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
    GridMode gridMode,
    boolean isApplied,
    boolean isChildExist,
    boolean isChildAttachment)
    { 
      // ...
    }
}

然后,我為每個記錄數據調用了以下構造函數。

public RowWidget(DataRawType dataRawType, Data data, Data parentData) {
 // ...
}

我認為這是不正確的方法。 因為當任何人看到此類然后理解它時,它將作為模式來創建一行。 我不想最初調用initWidget 我只想像構造函數那樣傳遞每個必需的參數

public RowWidget(DataRawType dataRawType,
  Data data,
  Data parentData,
  Form form,
  HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
  GridMode gridMode,
  boolean isApplied,
  boolean isChildExist,
  boolean isChildAttachment) {
  // ...
}

但是由於這個原因,構造函數沒有參數。 而且我認為在構造函數中有5個以上的參數也是一種不好的模式。

是否有人建議我:

  • 如何構造在另一個實例中具有相同屬性的類?

注意 :我知道這只能通過靜態實現,但不想使用靜態。

  • 對所有實例都具有一些默認的fix屬性,構造類的最佳方法是什么?

注意 :我不想創建另一個類來實現它。 或任何getter / setter方法。

提前致謝。

我會建議建造者模式。 您將需要一個額外的類來創建RowWidget對象。 因此,呼叫將如下所示:

RowWidget widget = new RowWidget.Builder().withData(data).withParentData(parentData).withDataRawType(dataRawType).build();

這是該模式的簡潔說明: https : //stackoverflow.com/a/1953567/991164

為什么不創建一個方法,該方法將接受要更改的屬性的newValues並返回類的新實例,並從調用此方法的實例中復制所有其他屬性。

如何構造在另一個實例中具有相同屬性的類?

為此,您可以擁有一個具有所有所需屬性的超類。 因此,擴展此超類的任何類都將具有這些屬性。 這樣,您無需使用static關鍵字。

對所有實例都具有一些默認的fix屬性,構造類的最佳方法是什么?

為此,您可以擁有一個具有某些常量屬性的接口。 這樣,任何實現此接口的類都將具有固定的屬性。

你可以分離/提取從參數RowWidget在-class來回例子RowWidgetConfig -class。

class RowWidgetConfig {
    // put here all your parameters that you need to initialize only once
    // init using setters
}

現在,創建該類的實例一次,並將其在其他參數中傳遞給RowWidget構造函數。

另一個選擇是擁有用於創建RowWidget實例的factory 工廠還將包含行實例所需的所有參數,以及工廠方法createNewRowWidget並根據工廠中包含的參數創建實例。

class RowWidgetFactory {
    // put here all your parameters that you need to initialize only once
    // init using setters

    public RowWidget createNewRowWidget() {
        // create
        return ...
    }
}

靜態的initWidget()東西對我來說似乎不合適。 盡管現在可能只有一組共享某些屬性的RowWidget ,但也有兩組RowWidget也是合理的,每組將具有自己的“共享”屬性。 如果您重構代碼以進行更合理的設計,那么事情將會更加流暢,並且在構建更合理的API時您將有更多選擇。

假設現在我介紹一個類似RowGroup的東西(代表您提到的“共享”東西)

(老實說,我並沒有完全理解您的設計,我只是根據您的代碼進行設計);

public class RowGroup {
    public RowGroup(Form form,
                    HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
                    GridMode gridMode,
                    boolean isApplied,
                    boolean isChildExist,
                    boolean isChildAttachment) { .... }

    public void addRow(DataRawType dataRawType, Data data, Data parentData) {...}
}

當人們使用時,它看起來像:

RowGroup rowGroup = new RowGroup(form, permissionMap, gridMode, isApplied, isChildExist, isChildAttach);
rowGroup.addRow(DataRawType.A, dataA, parentA);
rowGroup.addRow(DataRawType.B, dataB, parentB);

您甚至可以提供類似構建器的語法或許多其他選擇。

RowGroup rowGroup 
        = new RowGroup(.....)
              .addRow(DataRawType.A, dataA, parentA)
              .addRow(DataRawType.B, dataB, parentB);

更重要的是,現在的設計對我來說更有意義。

如果您不想創建另一個類,我建議A4L建議。 如果不創建另一個類,我將創建一個構造函數,該構造函數將使用所有參數和將當前實例用作模板的工廠方法,並將其自己的參數傳遞給構造函數參數。

示例(省略明顯的部分)

class A{
  public A(int p1, int p2){...}
  public A create(int p2) {
    return new A(this.p1,p2);
}

暫無
暫無

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

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