Skip to content

Commit fb7b1ae

Browse files
committed
refactor: extract TargetingRuleFactory from ParsedSplit
- Create TargetingRuleFactory with static buildTargetingRule() method - Eliminate FQNs for io.split.rules.model types - Add comprehensive tests for factory methods - Update ParsedSplit to delegate to factory This improves testability and separation of concerns by isolating the mapping logic from SDK domain objects to targeting-engine objects. AI-Session-Id: 7d0b171a-a576-4317-965f-99fb98c11ba8 AI-Tool: claude-code AI-Model: unknown
1 parent 7c06d4f commit fb7b1ae

File tree

3 files changed

+382
-36
lines changed

3 files changed

+382
-36
lines changed

client/src/main/java/io/split/engine/experiments/ParsedSplit.java

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static ParsedSplit createParsedSplitForTests(
6868
flagSets,
6969
impressionsDisabled,
7070
prerequisitesMatcher,
71-
buildTargetingRule(feature, seed, killed, defaultTreatment, matcherAndSplits, trafficTypeName,
71+
TargetingRuleFactory.buildTargetingRule(feature, seed, killed, defaultTreatment, matcherAndSplits, trafficTypeName,
7272
changeNumber, 100, seed, algo, null, flagSets, impressionsDisabled, prerequisitesMatcher)
7373
);
7474
}
@@ -102,7 +102,7 @@ public static ParsedSplit createParsedSplitForTests(
102102
flagSets,
103103
impressionsDisabled,
104104
prerequisitesMatcher,
105-
buildTargetingRule(feature, seed, killed, defaultTreatment, matcherAndSplits, trafficTypeName,
105+
TargetingRuleFactory.buildTargetingRule(feature, seed, killed, defaultTreatment, matcherAndSplits, trafficTypeName,
106106
changeNumber, 100, seed, algo, configurations, flagSets, impressionsDisabled, prerequisitesMatcher)
107107
);
108108
}
@@ -126,7 +126,7 @@ public ParsedSplit(
126126
this(feature, seed, killed, defaultTreatment, matcherAndSplits, trafficTypeName, changeNumber,
127127
trafficAllocation, trafficAllocationSeed, algo, configurations, flagSets,
128128
impressionsDisabled, prerequisitesMatcher,
129-
buildTargetingRule(feature, seed, killed, defaultTreatment, matcherAndSplits, trafficTypeName,
129+
TargetingRuleFactory.buildTargetingRule(feature, seed, killed, defaultTreatment, matcherAndSplits, trafficTypeName,
130130
changeNumber, trafficAllocation, trafficAllocationSeed, algo, configurations,
131131
flagSets, impressionsDisabled, prerequisitesMatcher));
132132
}
@@ -284,39 +284,6 @@ public String toString() {
284284

285285
}
286286

287-
private static TargetingRule buildTargetingRule(
288-
String feature, int seed, boolean killed, String defaultTreatment,
289-
List<ParsedCondition> matcherAndSplits, String trafficTypeName, long changeNumber,
290-
int trafficAllocation, int trafficAllocationSeed, int algo,
291-
Map<String, String> configurations, HashSet<String> flagSets,
292-
boolean impressionsDisabled, PrerequisitesMatcher prerequisitesMatcher) {
293-
List<io.split.rules.model.Condition> conditions = matcherAndSplits == null
294-
? Collections.<io.split.rules.model.Condition>emptyList()
295-
: matcherAndSplits.stream()
296-
.map(ParsedSplit::toTargetingCondition)
297-
.collect(Collectors.toList());
298-
List<io.split.rules.model.Prerequisite> prereqs = prerequisitesMatcher == null
299-
? Collections.<io.split.rules.model.Prerequisite>emptyList()
300-
: prerequisitesMatcher.getPrerequisites() == null
301-
? Collections.<io.split.rules.model.Prerequisite>emptyList()
302-
: Collections.unmodifiableList(prerequisitesMatcher.getPrerequisites());
303-
return new TargetingRule(feature, seed, killed, defaultTreatment, conditions, trafficTypeName,
304-
changeNumber, trafficAllocation, trafficAllocationSeed, algo, configurations,
305-
flagSets == null ? new HashSet<>() : flagSets, impressionsDisabled, prereqs);
306-
}
307-
308-
private static io.split.rules.model.Condition toTargetingCondition(ParsedCondition c) {
309-
List<io.split.rules.model.Partition> partitions = c.partitions() == null
310-
? Collections.<io.split.rules.model.Partition>emptyList()
311-
: c.partitions().stream()
312-
.map(p -> new io.split.rules.model.Partition(p.treatment, p.size))
313-
.collect(Collectors.toList());
314-
io.split.rules.model.ConditionType condType = c.conditionType() == ConditionType.ROLLOUT
315-
? io.split.rules.model.ConditionType.ROLLOUT
316-
: io.split.rules.model.ConditionType.WHITELIST;
317-
return new io.split.rules.model.Condition(condType, c.matcher(), partitions, c.label());
318-
}
319-
320287
public Set<String> getSegmentsNames() {
321288
return parsedConditions().stream()
322289
.flatMap(parsedCondition -> parsedCondition.matcher().attributeMatchers().stream())
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.split.engine.experiments;
2+
3+
import io.split.rules.matchers.PrerequisitesMatcher;
4+
import io.split.rules.model.Condition;
5+
import io.split.rules.model.ConditionType;
6+
import io.split.rules.model.Partition;
7+
import io.split.rules.model.Prerequisite;
8+
import io.split.rules.model.TargetingRule;
9+
10+
import java.util.Collections;
11+
import java.util.HashSet;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.stream.Collectors;
15+
16+
public final class TargetingRuleFactory {
17+
18+
private TargetingRuleFactory() {
19+
throw new IllegalStateException("Utility class");
20+
}
21+
22+
public static TargetingRule buildTargetingRule(
23+
String feature, int seed, boolean killed, String defaultTreatment,
24+
List<ParsedCondition> matcherAndSplits, String trafficTypeName, long changeNumber,
25+
int trafficAllocation, int trafficAllocationSeed, int algo,
26+
Map<String, String> configurations, HashSet<String> flagSets,
27+
boolean impressionsDisabled, PrerequisitesMatcher prerequisitesMatcher) {
28+
29+
List<Condition> conditions = matcherAndSplits == null
30+
? Collections.emptyList()
31+
: matcherAndSplits.stream()
32+
.map(TargetingRuleFactory::toTargetingCondition)
33+
.collect(Collectors.toList());
34+
35+
List<Prerequisite> prereqs = prerequisitesMatcher == null
36+
? Collections.emptyList()
37+
: prerequisitesMatcher.getPrerequisites() == null
38+
? Collections.emptyList()
39+
: Collections.unmodifiableList(prerequisitesMatcher.getPrerequisites());
40+
41+
return new TargetingRule(feature, seed, killed, defaultTreatment, conditions, trafficTypeName,
42+
changeNumber, trafficAllocation, trafficAllocationSeed, algo, configurations,
43+
flagSets == null ? new HashSet<>() : flagSets, impressionsDisabled, prereqs);
44+
}
45+
46+
private static Condition toTargetingCondition(ParsedCondition c) {
47+
List<Partition> partitions = c.partitions() == null
48+
? Collections.emptyList()
49+
: c.partitions().stream()
50+
.map(p -> new Partition(p.treatment, p.size))
51+
.collect(Collectors.toList());
52+
53+
ConditionType condType = c.conditionType() == io.split.client.dtos.ConditionType.ROLLOUT
54+
? ConditionType.ROLLOUT
55+
: ConditionType.WHITELIST;
56+
57+
return new Condition(condType, c.matcher(), partitions, c.label());
58+
}
59+
}

0 commit comments

Comments
 (0)