How was your CodeVita interview experience

Command Pattern Questions (PHP)


I created a minimalist command pattern example in PHP after reading about it. I have a few questions ...

I will like to know if what I did is right. or maybe too minimal, thereby reducing the point of the command pattern

I was wondering if there is a difference in simply putting this into a simple function saying in class?

if is better suited to a class, wouldn't it be better if it was a static class so can i just call vs have to instantiate an object first?

The point of the command pattern is to isolate certain functions in one object (the command) so that it can be reused for several other objects (the commanders). Usually the commander also gives a recipient to the command, e.g. An object that the command is aimed at. For example:

In the example above, CarWash is the commander. The car is the receiver and the program is the actual commands. Of course, I could have had a doStandardWash () method in CarWash and made any command a method in CarWash, but that's less extensible. I had to add a new method and command whenever I wanted to add new programs. With the command pattern, I can just pass in new commands (think of callback) and just make new combinations:

Of course, you can also use the PHP closures or functions for this, but let's stick with OOP for this example. Another thing the commands come in handy is when you have more than one commander who needs the command functionality, e.g.

If we had hard-coded the wash logic in CarWash, we would now have to duplicate all of the code in the dude. And since a guy can do a lot of things (because he's human), the list of tasks he can do will add up to an awfully long class.

Often times, the Commander itself is also an instruction, so you can create a collection of instructions and stack them in a tree. Commands often offer an undo method as well.

Now, looking back at your LoginCommand, I would say that it doesn't make a lot of sense to do so. You don't have a command object (it's the global scope) and your command has no recipient. Instead, it returns to the commander (making the global scope the receiver). So your command doesn't really work on the receiver. It is also unlikely that you would need the abstraction into a command if you are only logging into one place at a time. In this case, I would agree that the LoginCommand is better placed in an authentication adapter, possibly with a strategy pattern:

You could make it a little more commanding:

You could add the method to the user of course, but then you'd have to set the database adapter to the user to do the authentication, e.g.

That would be possible too, but personally I don't understand why a user should have an authentication adapter. It doesn't sound like something a user should have. A user has the credentials required for an authentication adapter, but not the adapter itself. However, passing the adapter to the user method would be an option:

If you use ActiveRecord, your user will know the database anyway and you can just back up all of the above information and write all the authentication code into the user.

As you can see, it boils down to how you set up your application. And that brings us to the most important point: design patterns provide solutions to common problems and allow us to talk about them without having to define tons of terms beforehand. That's cool, but often you have to change the patterns in order for them to solve your specific problem. You can spend hours theorizing about architecture and the patterns to use, and you haven't written a single code. Don't think too much about whether a pattern matches the proposed definition 100%. Make sure your problem is resolved.

  • 3 u explained really well, i need sometime to digest it tho. THANK YOU SO MUCH!
  • 1 The concept of a "receiver" is always omitted from other explanations that I have found. I think these days we don't emphasize the receiver in the same block of code as we emphasize asynchronicity. Nice answer even 4 years later.
  • 1 Your first example doesn't seem to make sense, nothing happened to $ car.