Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在构造函数中传递参数的最佳方法_Java_Design Patterns - Fatal编程技术网

Java 在构造函数中传递参数的最佳方法

Java 在构造函数中传递参数的最佳方法,java,design-patterns,Java,Design Patterns,我有一个在表布局中创建行的类。行的创建取决于数据和元数据。由于元数据对于每一行都是相同的,比如显示/隐藏可见性属性等,所以我创建了元数据属性作为静态属性,并使用RowWidget的initWidget进行了一次初始化 举个例子: class RowWidget extends FlexTable{ public static void initWidget(Form form, HashMap<Long, ContractorPermissionEnum> formMo

我有一个在表布局中创建行的类。行的创建取决于数据和元数据。由于元数据对于每一行都是相同的,比如显示/隐藏可见性属性等,所以我创建了元数据属性作为静态属性,并使用
RowWidget
initWidget
进行了一次初始化

举个例子:

class RowWidget extends FlexTable{

  public static void initWidget(Form form,
    HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
    GridMode gridMode,
    boolean isApplied,
    boolean isChildExist,
    boolean isChildAttachment)
    { 
      // ...
    }
}
因为我认为这不是正确的方法。因为作为模式,当任何人看到这个类并理解它时,就会创建一行。我不想最初调用
initWidget
。我只想在构造函数中传递每个必需的参数

public RowWidget(DataRawType dataRawType,
  Data data,
  Data parentData,
  Form form,
  HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
  GridMode gridMode,
  boolean isApplied,
  boolean isChildExist,
  boolean isChildAttachment) {
  // ...
}
public行窗口小部件(DataRawType DataRawType,
数据,
数据父数据,
形式形式,
HashMap formModePermissionMap,
GridMode GridMode,
应用布尔值,
布尔isChildExist,
布尔值(isChildAttachment){
// ...
}
但由于这个原因,构造函数没有任何参数。我认为在构造函数中使用5+参数也是一种糟糕的模式

有人建议我:

  • 如何构造在另一个类中具有相同属性的类 实例
注意:我知道这只能通过静态实现,但不想使用静态

  • 使用默认修复程序构造类的最佳方法是什么 所有实例的属性
注意:我不想创建另一个类来实现它。或任何getter/setter方法


提前感谢。

为什么不创建一个方法,该方法将接受要更改的属性的新值,并返回一个新的类实例,其中包含从调用此方法的实例复制的所有其他属性

如何构造在另一个实例中具有相同属性的类

要实现这一点,您可以拥有一个具有所有所需属性的超类。因此,任何扩展这个超类的类都将具有这些属性。这样您就不需要使用
static
关键字

对于所有实例,构造具有一些默认修复属性的类的最佳方法是什么


对于这个,您可以有一个具有一些常量属性的接口。这样,实现此接口的任何类都将具有固定的属性。

您可以从
RowWidget
-class中分离/提取
RowWidgetConfig
-class中示例的参数

class RowWidgetConfig {
    // put here all your parameters that you need to initialize only once
    // init using setters
}
现在创建该类的一个实例,并将其与其他参数一起传递给
RowWidget
构造函数

另一种选择是使用
factory
创建
RowWidget
实例。工厂还将包含行实例所需的所有参数以及工厂方法
createNewRowWidget
witch,该方法基于工厂中包含的参数创建实例

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

    public RowWidget createNewRowWidget() {
        // create
        return ...
    }
}
静态initWidget()似乎不适合我。虽然现在您可能只有一组共享某些属性的
RowWidget
s,但是有两组
RowWidget
s也是合理的,每组都有自己的“共享”属性。如果您重构代码以进行更合理的设计,那么事情将更加流畅,在构建更合理的API方面您将有更多的选择

假设现在我引入了类似于RowGroup的东西(哪种代表您提到的“共享”的东西)

(老实说,我不太明白你的设计的意义,我只是根据你的代码编写的)

您甚至可以提供类似生成器的语法或许多其他选择

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

更重要的是,现在的设计对我来说更有意义。

如果您不想创建另一个类,我建议使用A4L的建议。 在不创建其他类的情况下,我将创建接受所有参数的构造函数和使用当前实例作为模板的工厂方法,并将自己的参数传递给构造函数参数

示例(添加明显的部分)


我建议你用建筑图案。您需要一个额外的类来创建RowWidget对象。所以这个电话看起来是这样的:

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

下面是对该模式的简洁解释:

如果您将布尔参数转换为
映射
,您可以减少参数列表的长度,就像您使用表单permissionsyeah I can所做的那样。让我们任何人都别再想办法了。好吧,如果你真的不想要任何新类,想要摆脱静态和长参数列表,那么这个肮脏的建议怎么样:使用
Map
保存你的参数,填充一次,然后将该映射传递给
RowWidget
constructor,并在构建时使用它们。这比使用长参数列表更糟糕,因为最后一个参数列表更明确地说明了类需要哪些参数,并且更可读/可维护。你也应该重新考虑你的设计。是什么阻碍了你引入新课程?@A4L呵呵,这正是我读《无新课程笔记》时的第一个想法,但我不敢提出建议;)@马尔科福伯格哈。。。这就是为什么它只是作为评论;-)警察说他不想再上一节课。“注意:我不想创建另一个类来实现它。”@MarcoForberg oops,我错过了这个细节:/但是我必须承认,我首先想到的是配置类;9@MarcoForberg我真的很好奇这是怎么做到的!我将删除此答案,因为它对OP.me也没有帮助!我认为一个配置类会很好,尽管他不想要一个新的类。我知道超级类,但请阅读我的问题。我不需要它。当没有控件具有相同属性时,需要AFAIK超类。这里我只有一个控件。对于初始化超类,我需要构造函数。正确的?所以我也要通过一些论点来说明…对吗?怎么做?@Bhumika:既然你对几个控件有相同的属性,那么你只需要在超类中定义它们,所以你只需要默认的无参数构造函数
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);
class A{
  public A(int p1, int p2){...}
  public A create(int p2) {
    return new A(this.p1,p2);
}
RowWidget widget = new RowWidget.Builder().withData(data).withParentData(parentData).withDataRawType(dataRawType).build();