我有一个具有各种属性的类,我想在它们周围编写一个包装器方法,以便更容易地循环它们。
某些属性会返回集合值,有些属性为单个值。我正在寻找最佳方法。
我的第一种方法是让包装器方法返回属性getter返回的内容。
public class Test {
public Object getValue(String propName) {
if ("attr1".equals(propName)) return getAttribute1();
else if ("attr2".equals(propName)) return getAttribute2();
else return null;
}
public List<String> getAttribute1() {
return Arrays.asList("Hello","World");
}
public String getAttribute2() {
return "Goodbye";
}
public static void main(String[] args) {
final Test test=new Test();
Stream.of("attr1","attr2")
.forEach(p-> {
Object o=test.getValue(p);
if (o instanceof Collection) {
((Collection) o).forEach(v->System.out.println(v));
}
else {
System.out.println(o);
}
});
}
}
这种方法的不足之处在于调用者必须自己测试结果是否是集合。
对于调用者来说无缝的其他方法是始终返回一个集合,即。包装器函数将单个值包装到Collection中。这里是一个HashSet,但我们可以设想一个特殊的,最小的1个元素列表。
public class TestAlt {
public Collection getValue(String propName) {
if ("attr1".equals(propName))
return getAttribute1();
else if ("attr2".equals(propName)) {
Set s = new HashSet();
s.add(getAttribute2());
return s;
}
else
return null;
}
public List<String> getAttribute1() {
return Arrays.asList("Hello", "World");
}
public String getAttribute2() {
return "Goodbye";
}
public static void main(String[] args) {
final TestAlt test = new TestAlt();
Stream.of("attr1", "attr2")
.forEach(p -> {
test.getValue(p).forEach(v -> System.out.println(v));
});
}
性能方面,设计明智,......您对这些方法的看法是什么?你有更好的想法吗?
答案 0 :(得分:0)
好吧,您可以将要对每个属性执行的操作传递给对象,然后让对象决定如何处理它。 E.g:
在课堂测试中:
public void forEachAttribute(String propName, Handler h) {
if ("attr1".equals(propName))
h.handle(getAttribute1());
else if ("attr2".equals(propName)) {
getAttribute2().forEach(o -> h.handle(o))
}
}
一个功能为Handler
的课程handle(String s)
就是你要做的。
如果您无法修改Test
,也可以将功能移到Test
public void forEachTestAttribute(Test t, String propName, Handler h)...
性能方面:这将删除if子句
设计明智:这会移除一个演员表,但会创建更多类。
*编辑:它还维护类型安全性,如果有多种属性(String
,int
等),您可以添加更多handle
- 函数,仍然保持类型安全。
答案 1 :(得分:0)
关于设计,我会将您的代码重写为:
<强> TestAlt.java 强>
import java.util.*;
import java.util.stream.Stream;
public class TestAlt {
private Map<String, AttributeProcessor> map = AttributeMapFactory.createMap();
public Collection getValue(String propName) {
return Optional
.ofNullable(map.get(propName))
.map(AttributeProcessor::getAttribute)
.orElse(Arrays.asList("default")); //to avoid unexpected NPE's
}
public static void main(String[] args) {
final TestAlt test = new TestAlt();
Stream.of("attr1", "attr2")
.forEach(p -> test.getValue(p).forEach(v -> System.out.println(v)));
}
}
<强> AttributeMapFactory.java 强>
import java.util.HashMap;
import java.util.Map;
public class AttributeMapFactory {
public static Map<String, AttributeProcessor> createMap() {
Map<String, AttributeProcessor> map = new HashMap<>();
map.put("attr1", new HiAttributeProcessor());
map.put("attr2", new ByeAttributeProcessor());
return map;
}
}
<强> AttributeProcessor.java 强>
import java.util.Collection;
public interface AttributeProcessor {
Collection<String> getAttribute();
}
<强> HiAttributeProcessor.java 强>
import java.util.Arrays;
import java.util.Collection;
public class HiAttributeProcessor implements AttributeProcessor{
@Override
public Collection<String> getAttribute() {
return Arrays.asList("Hello", "World");
}
}
<强> ByeAttributeProcessor.java 强>
import java.util.Arrays;
import java.util.Collection;
public class ByeAttributeProcessor implements AttributeProcessor{
@Override
public Collection<String> getAttribute() {
return Arrays.asList("Goodbye");
}
}
重点是你使用map和动态调度来摆脱if-else语句。
这种方法的主要优点是您的代码可以更灵活地进行进一步的更改。在这个小程序的情况下,它并不重要,并且是一种矫枉过正。但是,如果我们谈论大型企业应用程序,那么是的,它变得至关重要。