Skip to content

Commit 8cadd2c

Browse files
committed
feat(behavioral): add strategy pattern
1 parent 0850585 commit 8cadd2c

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

behavioral/strategy.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
type FamilyClass = {
2+
0: "lower-class";
3+
1: "working-class";
4+
2: "middle-class";
5+
3: "upper-class";
6+
};
7+
8+
interface Family {
9+
membersCount: number;
10+
currentClass: keyof FamilyClass;
11+
}
12+
13+
interface PriorityStrategy {
14+
order(data: Family[]): Family[];
15+
}
16+
17+
class DonationFoundation {
18+
private donationPerFamily = 10;
19+
20+
constructor(
21+
private donationFund: number,
22+
private priorityStrategy: PriorityStrategy
23+
) {}
24+
25+
private donate(family: Family) {
26+
this.donationFund -= this.donationPerFamily;
27+
family.currentClass += 1;
28+
}
29+
30+
help(families: Family[]) {
31+
const orderedFamilies = this.priorityStrategy.order(families);
32+
33+
orderedFamilies.forEach(this.donate);
34+
}
35+
36+
changeStrategy(priorityStrategy: PriorityStrategy) {
37+
this.priorityStrategy = priorityStrategy;
38+
}
39+
}
40+
41+
// in object oriented programming
42+
class FamilyMembersPriority implements PriorityStrategy {
43+
order(families: Family[]) {
44+
return families.sort((firstFamily, secondFamily) => {
45+
const firstFamilyImportance = firstFamily.membersCount;
46+
const secondFamilyImportance = secondFamily.membersCount;
47+
48+
return firstFamilyImportance - secondFamilyImportance;
49+
});
50+
}
51+
}
52+
53+
class FamilyClassPriority implements PriorityStrategy {
54+
order(families: Family[]) {
55+
return families.sort((firstFamily, secondFamily) => {
56+
const firstFamilyImportance = firstFamily.currentClass;
57+
const secondFamilyImportance = secondFamily.currentClass;
58+
59+
return firstFamilyImportance - secondFamilyImportance;
60+
});
61+
}
62+
}
63+
64+
// in functional programming
65+
type OrderStrategy = (families: Family[]) => Family[];
66+
67+
const orderByMembers: OrderStrategy = (families: Family[]) => {
68+
return families.sort((a, b) => a.membersCount - b.membersCount);
69+
};
70+
71+
const orderByClass: OrderStrategy = (families: Family[]) => {
72+
return families.sort((a, b) => a.currentClass - b.currentClass);
73+
};
74+
75+
// how client will use
76+
const families: Family[] = [
77+
{
78+
currentClass: 0,
79+
membersCount: 4,
80+
},
81+
{
82+
currentClass: 3,
83+
membersCount: 2,
84+
},
85+
];
86+
87+
// now we can change the priority strategy at runtime.
88+
const aurora = new DonationFoundation(1000, new FamilyClassPriority());
89+
90+
aurora.help(families);
91+
92+
aurora.changeStrategy(new FamilyMembersPriority());
93+
94+
aurora.help(families);
95+
96+
/**
97+
* Strategy method pros
98+
*
99+
* * open/close principle
100+
* * composition over inheritance
101+
* * isolate implementations and details
102+
*
103+
* Strategy method cons
104+
*
105+
* * overhead for not changing strategies (for example if we have only one strategy)
106+
*
107+
*/

0 commit comments

Comments
 (0)