Good Architecture question

Hello there. I have an architecture question.

I have 3 MIS’s (Management Information systems) SystemA, SystemB and SystemC

  • Each class shares a common interface.

  • I want each of them to extend from CApplicationComponent so I can use magic getters, setters etc…

The MIS is a setting within the app e.g. $mis="systemb";

I want to be able to call something like Yii::app()->mis->getStuffFromMIS() and have the correct class return the results.

Here is a really dirty way of doing it:

In my main.php config file I have




	     //COMPONENTS

	    'systema'=>array(

	        'class'=>'application.components.PtSystemAComponents',

	        ),


	    'systemb'=>array(

	        'class'=>'application.components.PtSystemBComponents',

	        ),




	    'systemc'=>array(

	        'class'=>'application.components.PtSystemCComponents',

	        ),



I then call:




$mis=Yii::app()->systemSettings->schoolMis(); //Some method that returns systema, systemb or systemc

Yii::app()->$mis->getStuffFromMis();



However, this is really ugly.

What is the best architecture to use to call a central class which in turn instantiates the correct class and returns the results. Obviously I am trying to avoid using hundreds of IF, THEN or SWITCH statements within 1 class.

I am sure the experienced Yii developers among you will have come across this pattern several time but I just cannot see it right now. I hope I have explained my problem clearly enough.

Many thanks.

You could use factory pattern combined with singleton pattern to get proper MIS object by name. This way it would not be an CApplicationComponent but CComponent (you can still use magic getters). In this scenario you would code:




$mis = Yii::app()->systemSettings->schoolMis();

MisFactory::getMis( $mis )->getStuffFromMis();



This is just a proposition, as you can solve this problem in many ways :)

Many thanks. That’s a good place to start. I was beginning to come to the conclusion that this would not be possible using CApplicationComponent and you have confirmed that for me. I will try and aim for:




MisFactory::getMis()->getStuffFromMis();



and include the $mis discovery within the class.