重复的Java构造函数(重构或生成) 有问题的

重复的Java构造函数(重构或生成) 有问题的,java,refactoring,code-generation,documentation-generation,Java,Refactoring,Code Generation,Documentation Generation,我一直在为我在Java中使用的框架制作一个库:我使用了数百个LOC,纯粹是为了向用户提供许多构造函数,但每次都少了一个参数,因为可以使用默认值。这会导致大量重复的代码和大量重复的JavaDoc。最重要的是,只要有一点变化,就需要进行大量维护 解决方案示例 我觉得可能存在一些类似于Lombok的库,它允许我以这样一种方式注释构造函数,它将自动生成构造函数及其关联的JavaDoc。比如: /**一些描述*/ 公共类示例{ /**备选说明1*/ 公共物品替代品1; /**备选说明2*/ 公共其他对象替

我一直在为我在Java中使用的框架制作一个库:我使用了数百个LOC,纯粹是为了向用户提供许多构造函数,但每次都少了一个参数,因为可以使用默认值。这会导致大量重复的代码和大量重复的JavaDoc。最重要的是,只要有一点变化,就需要进行大量维护

解决方案示例 我觉得可能存在一些类似于Lombok的库,它允许我以这样一种方式注释构造函数,它将自动生成构造函数及其关联的JavaDoc。比如:

/**一些描述*/ 公共类示例{ /**备选说明1*/ 公共物品替代品1; /**备选说明2*/ 公共其他对象替代2; /**属性1描述*/ 公共int属性1=1; /**属性2描述*/ 公共int属性2=2; @注入类文档 @内射属性文档 公共示例@ConstructorRequiredVariant SomeObject obj, @ConstructorOrderedCascade int attribute1, @ConstructorOrderedCascade int attribute2{ 剂量测定法; } @注入类文档 @内射属性文档 公共示例@ConstructorRequiredVariant SomeOtherObject obj, @ConstructorOrderedCascade int attribute1, @ConstructorOrderedCascade int attribute2{ 剂量测定法; } //接球手和接球手 } 这将产生如下结果:

/**一些描述*/ 公共类示例{ /**备选说明1*/ 公共某物某物; /**备选说明2*/ 公共SomeOtherObject SomeOtherObject; /**属性1描述*/ 公共int属性1=1; /**属性2描述*/ 公共int属性2=2; /** *一些描述。 *@param obj备选方案1说明。 *@param attribute1 attribute1说明。 *@param attribute2 attribute2说明。 */ 公共示例最终SomeObject obj, 最终整数属性1, 最终整数属性2{ 此对象,属性1; setAttribute2attribute2; } /** *一些描述。 *@param obj备选方案1说明。 *@param attribute1 attribute1说明。 */ 公共示例最终SomeObject obj, 最终整数属性1{ thisobj; 设置属性1属性1; } /** *一些描述。 *@param obj备选方案1说明。 */ 公共示例最终SomeObject obj{ setSomeObjectobj; 剂量测定法; } /** *一些描述。 *@param obj Alternate2说明。 *@param attribute1 attribute1说明。 *@param attribute2 attribute2说明。 */ 公共示例最终SomeOtherObject obj, 最终整数属性1, 最终整数属性2{ 此对象,属性1; setAttribute2attribute2; } /** *一些描述。 *@param obj Alternate2说明。 *@param attribute1 attribute1说明。 */ 公共示例最终SomeOtherObject obj, 最终整数属性1{ thisobj; 设置属性1属性1; } /** *一些描述。 *@param obj Alternate2说明。 */ 公共示例最终SomeOtherObject obj{ 设置someotherobjectobj; 剂量测定法; } //接球手和接球手 } 这个问题的真实例子 这只是为了让你更好地了解我的来历

以下是我的问题来源的摘录:

/**在用户看到的所有构造函数上重用的一些描述*/ 公共类扩展了RadialGroup{ /**内部用于RadialWidgets的构造函数之间的共享属性*/ 受保护的空构造函数CommonTextureRegion whitePixel{ this.whitePixel=whitePixel; } /**内部用于RadialWidgets的构造函数之间的共享属性*/ 受保护的PieWidgetfinal纹理区域白色像素,浮点首选半径{ 超红半径; 构造器公共白像素; } /**内部用于RadialWidgets的构造函数之间的共享属性*/ 受保护的PieWidgetfinal纹理区域whitePixel, 浮动首选半径,浮动内半径百分比{ 超参考半径、内半径百分比; 构造器公共白像素; } /**内部用于RadialWidgets的构造函数之间的共享属性*/ 受保护的PieWidgetfinal纹理区域whitePixel, 浮动首选半径、浮动内半径百分比、浮动起始角度偏移{ 超参考半径、内半径百分比、起始角度偏移; 构造器公共白像素; } /**内部用于RadialWidgets的构造函数之间的共享属性*/ 受保护的PieWidgetfinal纹理区域whitePixel, 浮动首选半径,浮动内半径百分比, 浮动开始度偏移,浮动总度数已绘制{ 超参考半径、内半径百分比、起始角度偏移、绘制的总度数; 构造器公共白像素; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param style定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 */ public PiewigetFinal TextureRegion whitePixel, PieWidgetStyle样式,浮点首选半径{ 此白色像素,首选半径; 风格风格; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param style定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 */ public PiewigetFinal TextureRegion whitePixel, PieWidgetStyle样式,浮点首选半径, 浮动内半径百分比{ 此白色像素,首选半径,内半径百分比; 风格风格; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param style定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 */ public PiewigetFinal TextureRegion whitePixel, PieWidgetStyle样式,浮点首选半径, 浮动内半径百分比,浮动起始角度偏移{ 此白像素、首选半径、内半径百分比、起始角度偏移; 风格风格; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param style定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 *@param totalDegreesDrawed定义如何绘制的{@link totalDegreesDrawed} *小部件将跨越许多度,从 *它的{@link startDegreesOffset}。 */ public PiewigetFinal TextureRegion whitePixel, PieWidgetStyle样式,浮点首选半径, 浮动内半径百分比、浮动起始角度偏移、浮动总度数已绘制{ 此白像素、首选半径、内半径百分比、起始角度偏移、绘制的总度数; 风格风格; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 */ public PiewigetFinal TextureRegion whitePixel, 皮肤,漂浮半径{ 此白色像素,首选半径; setStyleskin.getPieWidgetStyle.class; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 */ 公共场所 gion whitePixel, 皮肤皮肤,漂浮半径, 浮动内半径百分比{ 此白色像素,首选半径,内半径百分比; setStyleskin.getPieWidgetStyle.class; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 */ public PiewigetFinal TextureRegion whitePixel, 皮肤皮肤,漂浮半径, 浮动内半径百分比,浮动起始角度偏移{ 此白像素、首选半径、内半径百分比、起始角度偏移; setStyleskin.getPieWidgetStyle.class; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 *@param totalDegreesDrawed定义如何绘制的{@link totalDegreesDrawed} *小部件将跨越许多度,从 *它的{@link startDegreesOffset}。 */ public PiewigetFinal TextureRegion whitePixel, 皮肤皮肤,漂浮半径, 浮动内半径百分比、浮动起始角度偏移、浮动总度数已绘制{ 此白像素、首选半径、内半径百分比、起始角度偏移、绘制的总度数; setStyleskin.getPieWidgetStyle.class; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param style要从蒙皮中提取的样式的名称。 *@param preferredRadius定义 *小部件的大小。 */ public PiewigetFinal TextureRegion whitePixel, 蒙皮蒙皮、字符串样式、浮动首选半径{ 此白色像素,首选半径; setStyleskin.getstyle,PieWidgetStyle.class; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param style要从蒙皮中提取的样式的名称。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 */ public PiewigetFinal TextureRegion whitePixel, 蒙皮、字符串样式、浮动首选半径、, 浮动内半径百分比{ 此白色像素,首选半径,内半径百分比; setStyleskin.getstyle,PieWidgetStyle.class; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param style要从蒙皮中提取的样式的名称。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 */ public PiewigetFinal TextureRegion whitePixel, 蒙皮、字符串样式、浮动首选半径、, 浮动内半径百分比,浮动起始角度偏移{ 此白像素、首选半径、内半径百分比、起始角度 抵消 setStyleskin.getstyle,PieWidgetStyle.class; } /** *有关说明,请参见{@link PieWidget}。 * *@param whitePixel一个1x1的白色像素。 *@param skin定义小部件的外观。 *@param style要从蒙皮中提取的样式的名称。 *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 *@param totalDegreesDrawed定义如何绘制的{@link totalDegreesDrawed} *小部件将跨越许多度,从 *它的{@link startDegreesOffset}。 */ public PiewigetFinal TextureRegion whitePixel, 蒙皮、字符串样式、浮动首选半径、, 浮动内半径百分比、浮动起始角度偏移、浮动总度数已绘制{ 此白像素、首选半径、内半径百分比、起始角度偏移、绘制的总度数; setStyleskin.getstyle,PieWidgetStyle.class; } // ... 然后开始实际的方法 } 父类:

公共类RadialGroup扩展了WidgetGroup{ /**内部用于RadialWidgets的构造函数之间的共享属性*/ 受保护的void构造函数公共{ setTouchableTouchable.childrenOnly; } /** *有关说明,请参见{@link RadialGroup}。 * *@param preferredRadius定义 *小部件的大小。 */ public RadialGroupfloat preferredRadius{ setPreferredRadiuspreferredRadius; 公共建筑; } /** *有关说明,请参见{@link RadialGroup}。 * *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 */ public RadialGroupfloat preferredRadius,float innerRadiusPercent{ 这是首选半径; setInnerRadiusPercentinnerRadiusPercent; } /** *有关说明,请参见{@link RadialGroup}。 * *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 */ public RadialGroupfloat preferredRadius,float innerRadiusPercent, 浮动起始角度偏移{ 此首选半径,内半径百分比; 设置开始度偏移设置开始度偏移; } /** *有关说明,请参见{@link RadialGroup}。 * *@param preferredRadius定义 *小部件的大小。 *@param innerradiupercent定义的{@link innerradiupercent} *被截断半径的百分比, *从小部件的中心开始。 *@param startDegreesOffset定义的{@link startDegreesOffset} *图形开始时距原点的距离。 *@param totalDegreesDrawed定义如何绘制的{@link totalDegreesDrawed} *小部件将跨越许多度,从 *它的{@link startDegreesOffset}。 */ public RadialGroupfloat preferredRadius,float innerRadiusPercent, 浮动开始度偏移,浮动总度数已绘制{ 此首选半径、内半径百分比、起始角度偏移; 设置TotalDegrees Draw到TotalDegrees Draw; } // ... } 结构相当简单:

有一个constructorsCommon方法用于对使用的任何构造函数执行公共操作。 构造函数本身也非常简单:它们使用与类的单个字段关联的setter,然后将调用传递给另一个构造函数,该构造函数定义的属性少了一个。 该类有3组构造函数:一组用于提供一个皮肤来实例化该类的不同方式,另一组是repli 对于可以为这3种方法中的所有方法设置的每个公共属性,设置4次。
我想知道是否有办法减少复制粘贴的代码和文档的数量。理想情况下,我将只使用3个构造函数,而不是12个。

为了避免在一个类有几个具有默认值的可选字段时编写成倍多的构造函数,可以使用。例如:

公开课范例{ 私人INTA; 私有字符串b; 私有字符c; 私有布尔d; 私有示例a、字符串b、字符c、布尔值d{ 这个a=a; 这个.b=b; 这个.c=c; 这个。d=d; } 公共静态类生成器{ //必填字段 私人INTA; 私有字符串b; //具有默认值的可选字段 私有字符c='c'; 私有布尔值d=false; 公共构建器a,字符串b{ 这个a=a; 这个.b=b; } 公共建筑商cchar c{ 这个.c=c; 归还这个; } 公共生成器dboolean d{ 这个。d=d; 归还这个; } 公共范例构建{ 返回新的示例A、b、c、d; } } }
然后你可以像new Example.Builder23,foo.c'y'.dfalse.build那样使用它来创建一个新对象,每个字段都有一个初始值,或者省略一些链式方法来使用这些字段的默认值。

不知何故,我没有考虑使用Builder模式作为解决方案,但这确实是一个好主意。但是,它会改变人们与库交互的方式,并提升版本,因为这是一个不向后兼容的更改,我正试图避免。我明白了。就我个人而言,我会实现Builder模式,但保留现有的公共构造函数,并将它们标记为已弃用,Javadoc会说改用Builder类。我不愿意长期维护和记录这么多类似的构造函数。但我理解你为什么会选择其他方式。