1010use OpenCF \Exceptions \EmptyDatasetException ;
1111use OpenCF \Exceptions \NotRegisteredRecommenderException ;
1212use OpenCF \Exceptions \NotSupportedSchemeException ;
13+ use ReflectionClass ;
14+ use ReflectionException ;
1315
1416class RecommenderService implements IRecommenderService
1517{
1618 /**
17- * @var IRecommender[]
19+ * list of registered engines.
20+ *
21+ * @var array<IRecommender>
1822 */
19- private array $ engines = [];
23+ private array $ recommenders = [];
2024
2125 /**
2226 * list of the supported Engines.
2327 *
24- * @var array
28+ * @var array<string>
2529 */
26- private array $ supportedEngines = [
27- ' Cosine ' ,
28- ' WeightedCosine ' ,
29- ' WeightedSlopeone ' ,
30+ private array $ defaultRecommenders = [
31+ Cosine::class ,
32+ WeightedCosine::class ,
33+ WeightedSlopeone::class ,
3034 ];
3135
3236 /**
@@ -42,6 +46,11 @@ class RecommenderService implements IRecommenderService
4246 public function __construct (array $ dataset )
4347 {
4448 $ this ->setDataset ($ dataset );
49+
50+ // register default recommenders
51+ foreach ($ this ->defaultRecommenders as $ recommender ) {
52+ $ this ->recommenders [$ recommender ] = new $ recommender ($ this ->dataset );
53+ }
4554 }
4655
4756 /**
@@ -62,35 +71,61 @@ public function setDataset(array $dataset = []): self
6271 return $ this ;
6372 }
6473
65- public function getRecommender ( string $ name ): IRecommender
74+ public function weightedSlopeone ( ): IRecommender
6675 {
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);
7078 }
7179
72- return $ this ->engines [ $ name ] ;
80+ return $ this ->getRecommender (WeightedSlopeone::class) ;
7381 }
7482
75- public function registerRecommender (string $ name ): self
83+ public function registerRecommender (string $ recommender ): self
7684 {
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));
8095 }
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 );
9199 }
92- $ this ->engines [$ recommendationEngine ->name ()] = $ recommendationEngine ;
93100
94101 return $ this ;
95102 }
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+ }
96131}
0 commit comments