Mmm....
1) Do you use an explicit approach, for example does the caller determine what filter get's replaced/overriden?
2) Do you use an automated/implicit approach. Does each filter have the intelligence to know which filters it is to disable (what arborint has suggested - I think?)?
I'm currently using an implicit approach. The module loading the filter, ideally, shouldn't know anything about the manager, the manager is the one who reads the module and figures the stuff out. However, the explicit approach may be more desirable.
Class heritage may be one path to automating the override status.. although that could produce poor behavior in some peoples' eyes.
Ooh, that's deep wizardry. But if a filter needs to disable two others, you're sunk. Probably not a good idea.
I think explicit is best for experienced programmers, but is that the audience?
Since this is more direct modifications into the code, I'd say experienced, but I want the learning curve as low as possible.
[snip]
Hmm... could I change the situation around a little bit? Here's what the code actually looks like:
Code: Select all
class Module
{
var $filters = array();
}
class Module_Wizardry extends Module
{
function Module_Wizardry() {
$this->filters[] = new Filter_DeepMagic();
}
}
class Schema
{
var $modules = array();
var $filters = array();
function Schema() {
$this->modules['Wizardry'] = new Module_Wizardry();
// more modules, dynamic and conditional loading, etc
}
function setup() {
foreach ($this->modules as $module) {
foreach ($module->filters as $filter) {
$this->filters[] = $filters;
}
}
}
}
And I'm lamenting how, with this setup, there's no way to disable Filter_DeepMagic if you want to override it with a new Filter_DeepBlueMagic.
A quick fix would be to use:
Code: Select all
class Module_Wizardry extends Module
{
// ...
function Module_Wizardry() {
$this->filters['DeepMagic'] = new Filter_DeepMagic();
}
}
class Module_SuperWizardry extends Module
{
// ...
function Module_SuperWizardry() {
$this->filters['DeepMagic'] = false; // remove filter
$this->filters['DeepBlueMagic'] = new Filter_DeepBlueMagic();
}
}
class Schema
{
// ...
function setup() {
foreach ($this->modules as $module) {
foreach ($module->filters as $filter_name => $filter) {
$this->filters[$filter_name] = $filters;
}
}
}
}
Integrating a manager would require a very major restructuring of the code:
Code: Select all
class Module_Wizardry extends Module
{
// ...
function loadFilters(&$manager) {
$manager->add(new Filter_DeepMagic());
}
}
class Schema
{
// ...
var $filterManager;
function setup() {
foreach ($this->modules as $module) {
$module->loadFilters($this->filterManager);
}
}
}
Like a Visitor pattern. You guys have run even further with it: the filter manager can implement all sorts of complicated overriding mechanisms:
1. Overriding based on inheritance (child class overrides parent)
2. Explicitly override another named filter (use a remove() function or something)
3. Query the filter object for information on inheritance (actually, one wouldn't need to pass in the manager to do that).
I'm wary about the third method because it's not very explicit. I'm wary about using the manager because it's very bulky.