Page 1 of 1

Command pattern

Posted: Wed Apr 30, 2008 5:51 am
by rimian
Hi,

I'm building myself a framework and I'm wondering about my controller (using the Command Pattern)... Should I use use one controller class for my node (module) with a switch or split it up into separate classes like:

Code: Select all

 
class Node_Command extends Command{
    function execute( $op ){
        switch($op){
            case 'add':
            //do add stuff
            break;
            case 'edit':
            //do edit stuff
            break;
 
            //etc etc
 
    }
}
 
OR!

Code: Select all

class Node_Add_Command extends Command{
    function execute( Command_Context $context ){
        //node add stuff
    }
}
class Node_Edit_Command extends Command{
    function execute( Command_Context $context ){
        //node edit stuff
    }
}
Any help much appreciated!

Re: Command pattern

Posted: Wed Apr 30, 2008 6:51 am
by Chris Corbyn
Switch statements in OO code often indicate a smell and suggest you should be using a strategy-like pattern. I'd say use your multiple objects if you're going to go down the command pattern route.

Take a look at the page controller pattern though; it's much more suited.

PS: If you're writing a framework I strongly urge you to start using PHP5 code. You're currently writing code in PHP4 by the look of things which is deprecated.

Re: Command pattern

Posted: Wed Apr 30, 2008 7:03 am
by onion2k
Chris Corbyn wrote:PS: If you're writing a framework I strongly urge you to start using PHP5 code. You're currently writing code in PHP4 by the look of things which is deprecated.
The type hinting (function execute( Command_Context $context )) would imply it's PHP5.

Re: Command pattern

Posted: Wed Apr 30, 2008 7:24 am
by Chris Corbyn
:oops: You got me! Usually when I've seen the Command pattern employed it's been via interface rather than a base class.

Code: Select all

interface Command {
  public function execute();
}

Re: Command pattern

Posted: Thu May 01, 2008 8:34 pm
by rimian
Yes, I am definately using php5. I didn't include the abstract class in my example for the sake of reading. I will take the advice on smelly code. Thanks! And I will also look at the page controller pattern.

I've avoided a switch statement by dynamically calling the function like so:

Code: Select all

 
class Node_Add_Command extends Command{
    function execute( Command_Context $context ){
        $operation = $context->get_op();
        $node = new Node();
        $node->$operation(); //must check my syntax here  
    }
}
 
Now I am wondering how to map the user authentication into this... and is this good practice? Will security be hard to enforce?

Thanks Chris, Onion2k.

PS: I will release this under GPL.

Re: Command pattern

Posted: Thu May 01, 2008 9:03 pm
by Christopher
You should really look at current practice. The code you showed above with the switch, and your double-dispatch code above is missing what is currently being implementing -- Action Controllers. Don't go back to Page Controllers. The whole point of using the Command pattern is because then all Actions have a common interface so they can be dispatched by a Front Controller. That is where the Command pattern comes into play.

Code: Select all

 
class Fooextends ActionController {  // it uses the Command pattern, but don't call it that
    function execute(){
    }
 
    function add(){
    }
 
    function edit(){
    }
 
    //etc etc
    }
}
The execute() or run() or index() action is the default action. Sometimes they add standard prefixes to everything:

Code: Select all

 
class FooController extends ActionController {
    function addAction(){
    }
 
    function editAction(){
    }
 
    //etc etc
    }
}

Re: Command pattern

Posted: Fri May 02, 2008 9:38 pm
by rimian
Yes! That's why I am here! To find out what the current practice is. I am reading through a few text books and studying hard but I need to apply these skills. This discussion is very helpful.

Thanks Christopher. I had revised my last example (in my head) and came up with something similar to what you just mentioned but not quite as elegant.

Re: Command pattern

Posted: Sat May 03, 2008 8:57 am
by koen.h
What's the current practice with a more complex layout? Eg I can imagine a forum application integrated in a CMS. The CMS uses a frontcontroller that calls an actioncontroller. Like in the examples that would be "forum extends actioncontroller".

But a forum itself could delegate to different controllers. Eg different commands for a topic (delete, edit, create, approve), for a category (edit, delete, etc).

Following the current practice example, having one forum controller, would that be implemented as this:

Code: Select all

 
class Forum extends ActionController {
    public createTopic()
    public deleteTopic()
    public createCategory()
    etc
}
 
This would lead to a bloated forumcontroller. So what to do in this case (when you would want to split up commands)?

Re: Command pattern

Posted: Sat May 03, 2008 12:28 pm
by Christopher
You would probably create multiple Action controllers to handle that:

Code: Select all

class Topic extends ActionController {
    public create()
    public delete()
    public edit()
    etc
}
 
class Category extends ActionController {
    public create()
    public delete()
    public edit()
    etc
}
So your URLS would be like "mysite.com?controller=topic&action=edit&id=5" or mysite.com/topic/delete/5".

Re: Command pattern

Posted: Sun May 04, 2008 3:36 pm
by koen.h
arborint wrote:You would probably create multiple Action controllers to handle that:

Code: Select all

class Topic extends ActionController {
    public create()
    public delete()
    public edit()
    etc
}
 
class Category extends ActionController {
    public create()
    public delete()
    public edit()
    etc
}
So your URLS would be like "mysite.com?controller=topic&action=edit&id=5" or mysite.com/topic/delete/5".
Guess that's more or less what they do in ZF with the addition that it would be " mysite.com/blog/topic/delete/5" to determine the topiccontroller from which app is called. Unless there's only one application but then the scenario of one class with commands is used.

Re: Command pattern

Posted: Sun May 04, 2008 3:53 pm
by Christopher
koen.h wrote:Guess that's more or less what they do in ZF with the addition that it would be " mysite.com/blog/topic/delete/5" to determine the topiccontroller from which app is called. Unless there's only one application but then the scenario of one class with commands is used.
ZF followed Rails in the URLs and Action Controllers. The code I posted would be the same in a module. The module parameter only selects the base directory to use for to find the controllers, models, views, etc.