Skip to content

Commit b029d26

Browse files
Add template method pattern with strategy integration (#15)
1 parent a7b3090 commit b029d26

File tree

11 files changed

+410
-0
lines changed

11 files changed

+410
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.luv2code</groupId>
8+
<artifactId>java-design-patterns</artifactId>
9+
<version>1.0</version>
10+
11+
<properties>
12+
<maven.compiler.source>24</maven.compiler.source>
13+
<maven.compiler.target>24</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
</properties>
16+
17+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
import java.util.Comparator;
4+
import java.util.List;
5+
6+
/**
7+
* Abstract base class for sorting strategies.
8+
*
9+
* Provides direction support (ascending/descending) for all subclasses.
10+
* Subclasses implement getComparator() to define their sorting criteria.
11+
*/
12+
public abstract class AbstractSortStrategy implements SortStrategy {
13+
14+
private final SortDirection direction;
15+
16+
// Default constructor
17+
protected AbstractSortStrategy() {
18+
this(SortDirection.ASCENDING);
19+
}
20+
21+
// Parameterized constructor
22+
protected AbstractSortStrategy(SortDirection direction) {
23+
if (direction == null) {
24+
throw new IllegalArgumentException("Sort direction must be non-null");
25+
}
26+
this.direction = direction;
27+
}
28+
29+
@Override
30+
public void sort(List<Course> courses) {
31+
Comparator<Course> comparator = getComparator();
32+
33+
if (direction == SortDirection.DESCENDING) {
34+
comparator = comparator.reversed();
35+
}
36+
37+
courses.sort(comparator);
38+
}
39+
40+
// Template method: subclasses provide the specific comparator
41+
protected abstract Comparator<Course> getComparator();
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
/**
4+
* Role: Element
5+
*
6+
* The element we will sort on.
7+
*/
8+
public class Course {
9+
10+
private String name;
11+
private double rating;
12+
private int studentCount;
13+
14+
public Course(String name, double rating, int studentCount) {
15+
this.name = name;
16+
this.rating = rating;
17+
this.studentCount = studentCount;
18+
}
19+
20+
public String getName() {
21+
return name;
22+
}
23+
24+
public void setName(String name) {
25+
this.name = name;
26+
}
27+
28+
public double getRating() {
29+
return rating;
30+
}
31+
32+
public void setRating(double rating) {
33+
this.rating = rating;
34+
}
35+
36+
public int getStudentCount() {
37+
return studentCount;
38+
}
39+
40+
public void setStudentCount(int studentCount) {
41+
this.studentCount = studentCount;
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return "Course{" +
47+
"name='" + name + '\'' +
48+
", rating=" + rating +
49+
", studentCount=" + studentCount +
50+
'}';
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
import java.util.List;
4+
5+
/**
6+
* Role: Context
7+
*
8+
* Maintains a reference to a SortStrategy and delegates sorting to it.
9+
* Allows clients to change sorting behavior by providing different strategies.
10+
*/
11+
public class CourseSorter {
12+
13+
private SortStrategy sortStrategy;
14+
15+
public CourseSorter(SortStrategy sortStrategy) {
16+
17+
if (sortStrategy == null) {
18+
throw new IllegalArgumentException("Sort strategy must be non-null");
19+
}
20+
21+
this.sortStrategy = sortStrategy;
22+
}
23+
24+
public void setSortStrategy(SortStrategy sortStrategy) {
25+
26+
if (sortStrategy == null) {
27+
throw new IllegalArgumentException("Sort strategy must be non-null");
28+
}
29+
30+
this.sortStrategy = sortStrategy;
31+
}
32+
33+
public void sort(List<Course> courses) {
34+
35+
if (courses == null) {
36+
throw new IllegalArgumentException("Courses must be non-null");
37+
}
38+
39+
sortStrategy.sort(courses);
40+
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* Role: Client
8+
*
9+
* Demonstrates the Strategy pattern by sorting courses using different strategies.
10+
* Shows how sorting behavior can be changed by providing different strategy implementations.
11+
* Can even change sorting strategy at runtime.
12+
*/
13+
public class MainApp {
14+
15+
public static void main(String[] args) {
16+
17+
List<Course> courses = new ArrayList<>();
18+
19+
Course course1 = new Course("JavaScript for Beginners", 4.8, 9800);
20+
Course course2 = new Course("Advanced Game Development", 4.5, 5000);
21+
Course course3 = new Course("Building Scalable Cloud Solutions", 4.9, 5000);
22+
23+
courses.add(course1);
24+
courses.add(course2);
25+
courses.add(course3);
26+
27+
System.out.println("=== Before Sorting ===");
28+
displayCourses(courses);
29+
30+
System.out.println();
31+
32+
// Create sorter with initial strategy (default ascending order)
33+
CourseSorter courseSorter = new CourseSorter(new NameSortStrategy());
34+
35+
System.out.println("=== Sort by name (ascending - default) ===");
36+
courseSorter.sort(courses);
37+
displayCourses(courses);
38+
39+
System.out.println();
40+
41+
// Change strategy at runtime with explicit descending order
42+
System.out.println("=== Sort by name (descending) ===");
43+
courseSorter.setSortStrategy(new NameSortStrategy(SortDirection.DESCENDING));
44+
courseSorter.sort(courses);
45+
displayCourses(courses);
46+
47+
System.out.println();
48+
49+
// Change to different sorting criteria with default ascending
50+
System.out.println("=== Sort by rating (ascending - default) ===");
51+
courseSorter.setSortStrategy(new RatingSortStrategy());
52+
courseSorter.sort(courses);
53+
displayCourses(courses);
54+
55+
System.out.println();
56+
57+
// Change to descending
58+
System.out.println("=== Sort by rating (descending) ===");
59+
courseSorter.setSortStrategy(new RatingSortStrategy(SortDirection.DESCENDING));
60+
courseSorter.sort(courses);
61+
displayCourses(courses);
62+
63+
System.out.println();
64+
65+
// Sort by student count ascending
66+
System.out.println("=== Sort by number of students (ascending - default) ===");
67+
courseSorter.setSortStrategy(new StudentCountSortStrategy());
68+
courseSorter.sort(courses);
69+
displayCourses(courses);
70+
71+
System.out.println();
72+
73+
// Sort by student count descending
74+
System.out.println("=== Sort by number of students (descending) ===");
75+
courseSorter.setSortStrategy(new StudentCountSortStrategy(SortDirection.DESCENDING));
76+
courseSorter.sort(courses);
77+
displayCourses(courses);
78+
79+
System.out.println();
80+
81+
// Sort by student count AND rating (ascending)
82+
System.out.println("=== Sort by number of students AND rating (ascending - default) ===");
83+
courseSorter.setSortStrategy(new StudentCountAndRatingSortStrategy());
84+
courseSorter.sort(courses);
85+
displayCourses(courses);
86+
87+
System.out.println();
88+
89+
// Sort by student count AND rating (descending)
90+
System.out.println("=== Sort by number of students AND rating (descending) ===");
91+
courseSorter.setSortStrategy(new StudentCountAndRatingSortStrategy(SortDirection.DESCENDING));
92+
courseSorter.sort(courses);
93+
displayCourses(courses);
94+
95+
}
96+
97+
private static void displayCourses(List<Course> courses) {
98+
99+
for (Course course : courses) {
100+
System.out.println(course);
101+
}
102+
103+
}
104+
}
105+
106+
107+
108+
109+
110+
111+
112+
113+
114+
115+
116+
117+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
import java.util.Comparator;
4+
5+
/**
6+
* Role: Concrete Strategy
7+
*
8+
* Sorts courses by name.
9+
*/
10+
public class NameSortStrategy extends AbstractSortStrategy {
11+
12+
public NameSortStrategy() {
13+
}
14+
15+
public NameSortStrategy(SortDirection direction) {
16+
super(direction);
17+
}
18+
19+
@Override
20+
protected Comparator<Course> getComparator() {
21+
return Comparator.comparing(Course::getName);
22+
}
23+
24+
}
25+
26+
27+
28+
29+
30+
31+
32+
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
import java.util.Comparator;
4+
5+
/**
6+
* Role: Concrete Strategy
7+
*
8+
* Sorts courses by rating.
9+
*/
10+
public class RatingSortStrategy extends AbstractSortStrategy {
11+
12+
public RatingSortStrategy() {
13+
}
14+
15+
public RatingSortStrategy(SortDirection direction) {
16+
super(direction);
17+
}
18+
19+
@Override
20+
protected Comparator<Course> getComparator() {
21+
return Comparator.comparingDouble(Course::getRating);
22+
}
23+
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
/**
4+
* Enum representing sort direction for sorting strategies.
5+
* Used to specify whether sorting should be in ascending or descending order.
6+
*/
7+
public enum SortDirection {
8+
ASCENDING,
9+
DESCENDING
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
import java.util.List;
4+
5+
/**
6+
* Role: Strategy
7+
*
8+
* Defines the interface for different sorting algorithms.
9+
* Allows the sorting behavior to be selected at runtime.
10+
*/
11+
public interface SortStrategy {
12+
13+
void sort(List<Course> courses);
14+
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.luv2code.designpatterns.behavioral.template;
2+
3+
import java.util.Comparator;
4+
5+
/**
6+
* Role: Concrete Strategy
7+
*
8+
* Sorts courses by student count, then by rating as a tiebreaker.
9+
*/
10+
public class StudentCountAndRatingSortStrategy extends AbstractSortStrategy {
11+
12+
public StudentCountAndRatingSortStrategy() {
13+
}
14+
15+
public StudentCountAndRatingSortStrategy(SortDirection direction) {
16+
super(direction);
17+
}
18+
19+
@Override
20+
protected Comparator<Course> getComparator() {
21+
return Comparator.comparingInt(Course::getStudentCount)
22+
.thenComparingDouble(Course::getRating);
23+
}
24+
25+
}
26+
27+
28+
29+
30+
31+
32+
33+

0 commit comments

Comments
 (0)