我正在编写一个函数,在这个函数中,我基本上一遍又一遍地做同样的事情。我有下面列出的功能
public String buildGarmentsString(List<Garment> garments)
{
StringBuilder garmentString = new StringBuilder(10000);
for(int i=0;i<4;i++)
{
garmentString.append(this.garmentProductId(i,garments.get(i).getProductId()));
garmentString.append(this.garmentColor(i,garments.get(i).getColor()));
for(int j=0;j<garments.get(i).getSizes().size();j++)
{
//check xxsml
if(garments.get(i).getSizes().get(j).getXxsml() >0)
{
garmentString.append(this.garmentSizes(i, Size.xxsml(),garments.get(i).getSizes().get(j).getXxsml()));
}
//check xsml
if(garments.get(i).getSizes().get(j).getXsml() > 0)
{
garmentString.append(this.garmentSizes(i,Size.xsml(),garments.get(i).getSizes().get(j).getXsml()));
}
//check sml
if(garments.get(i).getSizes().get(j).getSml() > 0)
{
garmentString.append(this.garmentSizes(i,Size.sml(),garments.get(i).getSizes().get(j).getSml()));
}
//check med
if(garments.get(i).getSizes().get(j).getMed() > 0)
{
garmentString.append(this.garmentSizes(i,Size.med(),garments.get(i).getSizes().get(j).getMed()));
}
//check lrg
if(garments.get(i).getSizes().get(j).getLrg() > 0)
{
garmentString.append(this.garmentSizes(i,Size.lrg(),garments.get(i).getSizes().get(j).getLrg()));
}
//check xlrg
if(garments.get(i).getSizes().get(j).getXlg() > 0)
{
garmentString.append(this.garmentSizes(i,Size.xlg(),garments.get(i).getSizes().get(j).getXlg()));
}
//check xxlrg
if(garments.get(i).getSizes().get(j).getXxl() >0)
{
garmentString.append(this.garmentSizes(i,Size.xxlg(),garments.get(i).getSizes().get(j).getXxl()));
}
//check xxxlrg
if(garments.get(i).getSizes().get(j).getXxxl() >0)
{
garmentString.append(this.garmentSizes(i,Size.xxxlg(),garments.get(i).getSizes().get(j).getXxxl()));
}
}
}
}
这是我的garmentSizes函数:
public String garmentSizes(int garmentNumber, String size,int numberToSend)
{
String garmentSizes = "&garment["+garmentNumber+"][sizes]["+size+"]="+numberToSend;
return garmentSizes;
}
我正在想办法用更少的代码来完成这项工作。我读过函数编程,你可以做一些事情,比如把函数传递给其他函数的参数。在网上做了一些阅读后,我想我想做这样的事情,但我不确定如何或什么是最好的方法
我在这里读了一些关于堆栈溢出的文章,我看到人们提到使用命令模式、FunctionalJava或LambdaJ来尝试在Java中近似此功能。我已经阅读了这两个库的文档,并阅读了维基百科上关于命令模式的文章,但我仍然不确定如何使用其中的任何一个来解决我的特定问题。有人能向我解释一下吗?作为一个从未做过任何函数式编程的人,这有点令人困惑。
- 您可以使用局部变量来减少重复次数。例如说
bySize = garments.get(i).getSizes().get(j)
- 您可以使用大小枚举和大小循环,而不是
size.getXxsml()
、size.getXsml()
等
然后整个事情看起来像:
for(int j=0;j<garments.get(i).getSizes().size();j++) {
bySize = garments.get(i).getSizes().get(j);
for (Size s : Size.values()) {
if (bySize.get(s) > 0) {
garmentString.append(garmentSizes(i, s, bySize.get(s)));
}
}
}
bySize.get(s)
方法可以通过指向正确方法的开关来实现,也可以直接在枚举中实现,并且可以去掉getXsml
等方法。
所有检查之间唯一不同的是:
getXxsml/xxsml, getXsml/xsml, getSml/sml, etc.
如果您可以将这些值(作为字符串)传递给某个上级方法,并且
该上级方法可以评估(即执行这些字符串),那么您就可以
拥有这些值的数组,并将该数组传递给该上级方法。
在Java中,您可以使用反射执行类似的操作
通过使用反射,所有这些检查确实可以简化为更少的
代码。
看看:java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Field
java.lang.reflect.Constructor
,你就会明白我的意思了。
从您的代码中可以看出,某些class具有以下方法:
xxsml(), xsml(), sml(), med(), ..., xxxlg()
以获得每个尺寸的可用数量(?)。
你可以更好地设计你的数据,比如:
- 具有枚举所有大小的"Size"类型(可以是Enum或具有属性
String key
的某个类) - 有一个返回所有已知大小的List的方法
- 将上述方法替换为
amountFor(Size)
这可以由Map<Size, Integer>
支持
为了向后兼容性,您可以按照以下行重写旧方法:
int xxsml() {
return amountFor(Size.XXSML); // assuming you have a singleton instance
// for each well known size
}
当然,在getGarmentString中,您将循环浏览所有已知尺寸的列表:
for (Size sz : Size.getAllKnownSizes()) {
if (garments.get(i).getSizes().get(j).amountFor(sz) > 0) {
... do whatever must be done here
}
}