Polymorphic / Plugable PHP Classes
Your approach is correct. It is a Strategy Pattern (UML diagram):
Check out my answer to this question (skip to where it says Since you want to dynamically change behavior):
- Can I include code into a PHP class?
An alternative to your specific UseCase would be to capsule the Selection Strategies into a single Service class, instead of assigning them to your Collection class. Then instead of passing the strategies to the collection, pass the collection to the Service Class, e.g.
class CollectionService implements ICollectionSelectionService
{
public static function select(MyCollection $collection, $strategy) {
if(class_exists($strategy)) {
$strategy = new $strategy;
return $strategy->select($collection);
} else {
throw new InvalidArgumentException("Strategy does not exist");
}
}
}
$element = CollectionService::select($myCollection, 'Alpha');
I leave it up to you whether to use this with static methods or not. To prevent multiple instantiation of Selection strategies, you could store the Selection objects inside the Service for reuse.
For other Behavioral Patterns check
- http://sourcemaking.com/behavioral_patterns
- http://www.fluffycat.com/PHP-Design-Patterns
- http://www.phppatterns.com/docs/?idx=design
The solution you outlined is more or less right. You may not know this, but this is in fact "State" Design Pattern. State of the system is represented by object. If you need to change the state, you just replace the object with another State.
I would recommend staying with what you have, as it's proven by GoF to be viable solution.