10
10
use OpenCF \Exceptions \EmptyDatasetException ;
11
11
use OpenCF \Exceptions \NotRegisteredRecommenderException ;
12
12
use OpenCF \Exceptions \NotSupportedSchemeException ;
13
+ use ReflectionClass ;
14
+ use ReflectionException ;
13
15
14
16
class RecommenderService implements IRecommenderService
15
17
{
16
18
/**
17
- * @var IRecommender[]
19
+ * list of registered engines.
20
+ *
21
+ * @var array<IRecommender>
18
22
*/
19
- private array $ engines = [];
23
+ private array $ recommenders = [];
20
24
21
25
/**
22
26
* list of the supported Engines.
23
27
*
24
- * @var array
28
+ * @var array<string>
25
29
*/
26
- private array $ supportedEngines = [
27
- ' Cosine ' ,
28
- ' WeightedCosine ' ,
29
- ' WeightedSlopeone ' ,
30
+ private array $ defaultRecommenders = [
31
+ Cosine::class ,
32
+ WeightedCosine::class ,
33
+ WeightedSlopeone::class ,
30
34
];
31
35
32
36
/**
@@ -42,6 +46,11 @@ class RecommenderService implements IRecommenderService
42
46
public function __construct (array $ dataset )
43
47
{
44
48
$ this ->setDataset ($ dataset );
49
+
50
+ // register default recommenders
51
+ foreach ($ this ->defaultRecommenders as $ recommender ) {
52
+ $ this ->recommenders [$ recommender ] = new $ recommender ($ this ->dataset );
53
+ }
45
54
}
46
55
47
56
/**
@@ -62,35 +71,61 @@ public function setDataset(array $dataset = []): self
62
71
return $ this ;
63
72
}
64
73
65
- public function getRecommender ( string $ name ): IRecommender
74
+ public function weightedSlopeone ( ): IRecommender
66
75
{
67
- if (! array_key_exists ($ name , $ this ->engines )) {
68
- throw new NotRegisteredRecommenderException (sprintf ('The Recommendation engine "%s" is not registered in the Recommender Service ' ,
69
- $ name ));
76
+ if (!in_array (WeightedSlopeone::class, $ this ->recommenders )) {
77
+ $ this ->registerRecommender (WeightedSlopeone::class);
70
78
}
71
79
72
- return $ this ->engines [ $ name ] ;
80
+ return $ this ->getRecommender (WeightedSlopeone::class) ;
73
81
}
74
82
75
- public function registerRecommender (string $ name ): self
83
+ public function registerRecommender (string $ recommender ): self
76
84
{
77
- if (! in_array ($ name , $ this ->supportedEngines )) {
78
- throw new NotSupportedSchemeException (sprintf ('The Recommendation engine "%s" is not supported yet ' ,
79
- $ name ));
85
+ try {
86
+ $ rf = new ReflectionClass ($ recommender );
87
+ } catch (ReflectionException $ e ) {
88
+ throw new NotSupportedSchemeException (sprintf ('Recommendation engine "%s" must implement "%s" interface ' ,
89
+ $ recommender , IRecommender::class));
90
+ }
91
+
92
+ if (!$ rf ->implementsInterface (IRecommender::class)) {
93
+ throw new NotSupportedSchemeException (sprintf ('Recommendation engine "%s" must implement "%s" interface ' ,
94
+ $ recommender , IRecommender::class));
80
95
}
81
- switch ($ name ) {
82
- case 'WeightedCosine ' :
83
- $ recommendationEngine = new WeightedCosine ($ this ->dataset );
84
- break ;
85
- case 'WeightedSlopeone ' :
86
- $ recommendationEngine = new WeightedSlopeone ($ this ->dataset );
87
- break ;
88
- default :
89
- $ recommendationEngine = new Cosine ($ this ->dataset );
90
- break ;
96
+
97
+ if (!in_array ($ recommender , $ this ->recommenders )) {
98
+ $ this ->recommenders [$ recommender ] = new $ recommender ($ this ->dataset );
91
99
}
92
- $ this ->engines [$ recommendationEngine ->name ()] = $ recommendationEngine ;
93
100
94
101
return $ this ;
95
102
}
103
+
104
+ public function getRecommender (string $ recommender ): IRecommender
105
+ {
106
+ if (!array_key_exists ($ recommender , $ this ->recommenders )) {
107
+ throw new NotRegisteredRecommenderException (sprintf ('The Recommendation engine "%s" is not registered in the Recommender Service ' ,
108
+ $ recommender ));
109
+ }
110
+
111
+ return $ this ->recommenders [$ recommender ]->buildModel ();
112
+ }
113
+
114
+ public function weightedCosine (): IRecommender
115
+ {
116
+ if (!in_array (WeightedCosine::class, $ this ->recommenders )) {
117
+ $ this ->registerRecommender (WeightedCosine::class);
118
+ }
119
+
120
+ return $ this ->getRecommender (WeightedCosine::class);
121
+ }
122
+
123
+ public function cosine (): IRecommender
124
+ {
125
+ if (!in_array (Cosine::class, $ this ->recommenders )) {
126
+ $ this ->registerRecommender (Cosine::class);
127
+ }
128
+
129
+ return $ this ->getRecommender (Cosine::class);
130
+ }
96
131
}
0 commit comments