[英]Avoiding code duplication for methods with different return types
我有两个生成器类,分别返回一个Tree
和一个Set
。 第二个构建器的执行只是第一个构建器的执行,带有额外的步骤和不同的返回类型。 我真的不想在两个不同的类中重复相同的步骤,因为如果在Tree
构建过程中进行了更改,则必须在两个类中更改代码。 这是两个构建器:
public class TreeBuilder {
private NodeHelper nodeHelper;
public TreeBuilder(NodeHelper nodeHelper) {
this.nodeHelper = nodeHelper;
}
public Tree<EquipmentDetails> buildTree() {
Tree<EquipmentDetails> tree = new Tree<>(nodeHelper.getEquipmentDetails(nodeHelper.getModelName()));
return buildTree(tree);
}
private Tree<EquipmentDetails> buildTree(Tree<EquipmentDetails> parentTree) {
Map<String, NativeSlotDisplayLabel> childSubTypeMap = nodeHelper.getChildSubTypeMap(parentTree);
if (CommonUtils.nullOrEmpty(childSubTypeMap))
return parentTree;
for (String holderCommonName : childSubTypeMap.keySet()) {
NativeSlotDisplayLabel nativeSlotDisplayLabel = childSubTypeMap.get(holderCommonName);
EquipmentDetails equipmentDetails = nodeHelper.constructEqptDetails(holderCommonName, nativeSlotDisplayLabel, parentTree);
Tree<EquipmentDetails> childTree = new Tree<>(equipmentDetails);
parentTree.addChild(childTree);
String equipmentCommonName = equipmentDetails.getModelEquipType();
if (equipmentCommonName == null)
continue;
buildTree(childTree);
}
return parentTree;
}
}
第二个构建器使用另一个依赖项,并返回Set
而不是Tree
:
public class FreePortsBuilder {
private NodeHelper nodeHelper;
private PortLabelGenerator portLabelGenerator;
public FreePortsBuilder(NodeHelper nodeHelper, PortLabelGenerator portLabelGenerator) {
this.nodeHelper = nodeHelper;
this.portLabelGenerator = portLabelGenerator;
}
public Set<PortNameAndLabel> collectFreePorts(){
Tree<EquipmentDetails> tree = new Tree<>(nodeHelper.getEquipmentDetails(nodeHelper.getModelName()));
Set<PortNameAndLabel> portNameAndLabels = new HashSet<>();
return collectFreePorts(tree, portNameAndLabels);
}
private Set<PortNameAndLabel> collectFreePorts(Tree<EquipmentDetails> parentTree, Set<PortNameAndLabel> portNameAndLabels) {
Map<String, NativeSlotDisplayLabel> childSubTypeMap = nodeHelper.getChildSubTypeMap(parentTree);
if (CommonUtils.nullOrEmpty(childSubTypeMap))
return portNameAndLabels;
Set<PortNameAndLabel> generatedPortNameAndLabel = portLabelGenerator.getPortNameAndLabel(childSubTypeMap, parentTree.getUserObject());
portNameAndLabels.addAll(generatedPortNameAndLabel);
for (String holderCommonName : childSubTypeMap.keySet()) {
NativeSlotDisplayLabel nativeSlotDisplayLabel = childSubTypeMap.get(holderCommonName);
EquipmentDetails equipmentDetails = nodeHelper.constructEqptDetails(holderCommonName, nativeSlotDisplayLabel, parentTree);
Tree<EquipmentDetails> childTree = new Tree<>(equipmentDetails);
parentTree.addChild(childTree);
String equipmentCommonName = equipmentDetails.getModelEquipType();
if (equipmentCommonName == null)
continue;
collectFreePorts(childTree, portNameAndLabels);
}
return portNameAndLabels;
}
}
我正在寻找一种避免重复的方法。 有什么建议么?
FreePortsBuilder
同时执行两项操作:
Tree
:如您所知,这与TreeBuilder
作用相同。 Set<PortNameAndLabel>
,其中每个PortNameAndLabel
似乎与最终Tree
的节点或子代(本身就是Tree
)相关联。 与其同时执行上述两件事,不如依次执行它们。 也就是说,在FreePortsBuilder
, 首先使用TreeBuilder
来构建Tree
, 然后遍历此Tree
来构建Set<PortNameAndLabel>
。 一种实现方法如下(我假设您的Tree
类具有类似getChildren()
的方法,该方法返回List<Tree<EquipmentDetails>>
)。
首先,允许客户端通过添加getter获得TreeBuilder
的NodeHelper
:
public class TreeBuilder {
private NodeHelper nodeHelper;
public NodeHelper getNodeHelper() {
return this.nodeHelper;
}
...
}
然后,注入TreeBuilder
代替NodeHelper
到FreePortsBuilder
( FreePortsBuilder
可以使用NodeHelper
是在TreeBuilder
,因为我们刚才添加的吸气剂):
public class FreePortsBuilder {
private TreeBuilder treeBuilder;
private PortLabelGenerator portLabelGenerator;
public FreePortsBuilder(TreeBuilder treeBuilder, PortLabelGenerator portLabelGenerator) {
this.treeBuilder = treeBuilder;
this.portLabelGenerator = portLabelGenerator;
}
public Set<PortNameAndLabel> collectFreePorts() {
Tree<EquipmentDetails> tree = treeBuilder.buildTree();
return collectFreePorts(tree);
}
private Set<PortNameAndLabel> collectFreePorts(Tree<EquipmentDetails> tree) {
Set<PortNameAndLabel> portNameAndLabels = new HashSet<>();
for (Tree<EquipmentDetails> child : tree.getChildren()) {
Map<String, NativeSlotDisplayLabel> childSubTypeMap =
treeBuilder.getNodeHelper().getChildSubTypeMap(child);
if (CommonUtils.nullOrEmpty(childSubTypeMap))
continue;
Set<PortNameAndLabel> generatedPortNameAndLabel =
portLabelGenerator.getPortNameAndLabel(childSubTypeMap, child.getUserObject());
portNameAndLabels.addAll(generatedPortNameAndLabel);
}
return portNameAndLabels;
}
}
现在, FreePortsBuilder
可以真正利用TreeBuilder
实现,并且删除了重复的代码。
您可以在此处使用策略设计模式或模板方法 。 您这里有一个算法,其中仅某些步骤会发生变化(collectFreePorts和buildTree)。
如果您不能使用继承,则可以使用类似的解决方案: https : //softwareengineering.stackexchange.com/questions/187872/template-method-within-one-class-without-subclasses-or-inheritance
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.