Design patterns are not restricted to OOP and a lot of implementations of OOP design patterns are written with some memory management in thought.
I come from the Java world and in Java you would have to use a strict OOP design pattern. Simply because everything in Java is an object. Sometimes you must create an object and a method even if it is actually not needed for the pattern itself. The factory method design pattern is such an example. It is very good to design by interface for the implementations of the factory, but you don't need a class and method to implement the factory. The reason that an implementation of a design pattern is sometimes confusing is that the programming language sometimes requires an implementation that is not strictly needed in the design pattern itself. The creation of a class with a method in the factory method is such an example.
My solution is not purely OOP, but PHP is that not too and in the long run is it not about OOP in my opinion, but about the best implementation of the design pattern factory method.
I think that the elegancy of PHP is that it combines best of both worlds. It delivers a solid OOP design possibility, yet it has not thrown away the good elements of procedural programming.
You can simply create code like this:
function createRequest($pRequesttype){ switch($pRequesttype){ case "cli": $tmp = new CliRequest(); break; case "http": $tmp = new HttpRequest(); break; default: $tmp = new DefaultRequest(); } return $tmp; }
Always return a default implementation to handle the request. A switch statement is the best choice to extend the number of choices in a software engineer friendly way.
Now have you the call php_sapi_name in your create function. I advice you to get it out the implementation of the function. It is best practice to let a function do one job only and getting the request and handling the request are two functions. Make a createRequest function that has a parameter like I showed you.
To answer your question: 1, 2 or 3? Uh, 4 actually. :-) If 1, 2 or 3?
Definitely 1, because I don't want to load too much classes for a simple method, but to simplify this situation I have proposed solution 4.
I would not use method 2, because it is not efficient to create a class for one moment in time. I would consider it best practice, but not the best practical implementation. If using this solution, then please also support the class with an interface for factories in general. Best OOP design, but not best practical implementation.
I would certainly not use method 3, because abstract classes are there to abstract data objects and interfaces to abstract behaviour. A factory method is an abstraction of an interface, never of an abstract class.
2)is the best one. However, you should passphp_sapi_nameas a parameter ofcreatemethod.new RequestFactory().