[英]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.