![]() |
Using the factory pattern (mad rantings of a mind without coffee)
Yo,
This is my first tutorial of sorts, i came across this method of doing things a few months ago when i needed some form of database abstraction. This is what i came up with (albeit this version is greatly stripped down to its core so that it will show the workings better), if you have any improvements to this method or if there are any better ways of doing it i'm open to ideas :) . The first point I'd like to make is the use of an interface in this script, its important to understand that i needed a database abstraction class and the interface allows me to specify which methods a class must implement, therefore i can have a mysql class and a mssql class, both must have the same methods so that the rest of the system will work the same when i decide i want to change over from mysql to mssql. For example i have a class called mysql, it has a method called query() for sending querys to the database, and i have used it in my system extensively, then i decide i don't want to use mysql anymore and i want to switch over the mssql. The new mssql class i code also has a query method, but without thinking i call it doQuery() or something, now the rest of the system where the method query() was called will fail. The interface allows you to apply a kind of rule to the class, so if i tried naming a method doQuery() and in the interface it said that it must have a query() method, PHP will throw an error and more importantly i don't have to go through hundreds of lines of code changing names of method calls. with that hopefully explained i can get on (hopefully) Right, i will be combining two patterns here really, the database object is instantiated with a factory pattern but the database object is singleton. here is the database classes and interface: PHP Code:
now the factory class, this will determine the type of database that we want to use, then create the object for us: PHP Code:
This static allows us to make the database object a singleton (read karl\'s great tutorial on the singleton design pattern, if your not sure what im going on about: http://www.talkphp.com/showthread.php?t=1304). Next i have a static method called factory, this is the method we call to create a database object, its static like the object pointer so that i don't actually have to have an instance of this class in order to use it, also at the start of the function name is the "&" symbol, this basically tells PHP the i will be returning a reference (returns by reference instead of by value). The method has a string param 'szType' with a blank default value, this will be how we tell the class which database type we need, for this example i will be using mysql. Next the string param goes into a switch but before it does it checks the static 'pDB' to see if there is already an object created, if there is just reuse that object, if there isn't it then creates the object from the correct class. notice that because 'pDB' is static it isn't instantiated in the object, so $this-> wont work as we don't have a reference to the current object ($this is a reference to the calling object which is usually the object to which the method belongs although it can be others too) thus we have to use the self keyword, along with the the Scope Resolution Operator "::" so that we can access the static variable 'pDB'. Because we have a default value of szType (szType = "") if nothing is passed into the method, the switch will go to the default (saves you having to type the database type if the default is all you need) or alternatively you could have a named constant in config file or something. right moving on, inside the switch (after it has determined the type, for example we have passed in the string 'mysql' into the param) it goes and creates an instance of the class 'DBmysql' then assigns the static variable 'pDB' with the reference to that object, then returns the reference of the reused/newly created object, out of the method. To use this we could do this: PHP Code:
PHP Code:
PHP Code:
(i appologise if its seems a bit jumbled and crazy, its just they way i am when i havent had my daily coffee to calm my brain down abit, so basicly this tutorial is a result of my coffee withdrawal insanity) ciao for now |
That looks really awesome! :D
Great article :) Although, I still don't understand why you use interface here =// Is there any article on this site explaining the advantage of interfaces? |
hehe i didnt get them at first, and i guess my explanation was a bit lacking.
i havnt seen any articles on this site that explain interfaces, my applogies if i have missed them. Ill have another go at explaining them :D Basicly the interface is there as a kind of template for any classes that implement it i.e. PHP Code:
PHP Code:
Our interface looks like this: PHP Code:
implemented class looks like this: PHP Code:
Its not totally neccisary but it really helps, especially when you havent coded it yourself, for example someone within the development team (who didnt develop the exsisting system) has been told to extend the system and add support for oracle, instead of reading through all the code finding out the different method names within the exsisting database classes, with an interface he is able to open the interface and find out right away all the method names so he can code the new class accordingly and be 100% sure that when he tries his new oracle class it will work 100% with the rest of the system (as the api will be the same). To sum it up: Basically, an interface is a contract or a blueprint. When you implement an interface, you must always implement the methods, propeties, and params that it asks of you. In this case it ensures that any new databse connection class will have the same api that the other classes use therefore will have the same api that the rest of the system uses, enabling a smooth transition of database providers, without having to redesign everything again. i hope i have made things a bit clearer, it confused the hell out of me for a while but it does eventually make sense, especially when you start using it for projects with more than one coder. |
That was a really good explenation!
However, if I have an interface like you said, can I use other functions ASWELL as the ones in the interface, in the class that implents the interface?? |
Yes you can, aslong as the implemented class contains at least all of the methods etc in the interface you can have extra methods in the implemented class.
An important note that i forgot is that the interface class is a totally abstracted class, in other words it doesnt do anything, there are no workings or body to it, it has methods etc but no guts to it, its up to the implemented classes to take care of that. glad you liked it :) |
Thanks for contributing sketch, there's some good information in this thread.
|
I have another question.
Your static function factory, can I name it something else? PHP Code:
PHP Code:
|
Yes you can name it something else, it needn't necessarily be called factory.
|
Okey! But I do need the "&" sign before the name of the function?
|
I may be wrong, but i believe you do not need the & before the function name. As PHP since PHP 5 does class/function referencing by default, and seen as though this is PHP 5 OOP, its not needed.
Disclaimer: I've never really understood this ampersand crap in the past, so don't quote me on anything! :D But I'm 90% sure its just for making a reference when refering to a variable/class/function instead of cloning it. |
Okey, I have another question.
Let's say I have DBmysql.php, and in it I have the class for mysql. I also have DBoracle.php, and in it I have the class for oracle. Then I have the file DB.php, where I have this static function.. how would I make an object of classes in other files? PHP Code:
|
hey,
sorry i havent posted in a while, ive been busy. anyway bluesaga is correct about PHP5 and referencing, i do know that the new keyword returns a reference by default but i am unsure about returning from functions and i must admit i havent tested to see (if sum1 else knows please let me know :) ). @Tanax i am unsure about your question, can u elaborate more? just add to the switch for oracle (if thats what your question was :confused:) |
Quote:
My question was that if I have several database classes, for instance mysql, mssql, and oracle. Then I will have the switch, and creates objects of the class depending on what type. But how will it create an object of a class, in ANOTHER file. I have this DBfactory.php where the static factory method is. Then I have a new file for each of the database types. DBmysql.php DBmssql.php DBoracle.php Which means, that I have to include them in order to create the object like so: PHP Code:
Like this? PHP Code:
|
Sorry my brain cant compute (out of coffee here atm :( )
what it looks like to me is that u want to know how you would extend the script to include, for example, oracle? like this: PHP Code:
PHP Code:
lets say, $type = 'oracle' u dont really need concat the value of type into the include as its a switch so type will always be equal to 'oracle' otherwise it wouldnt have fired that line if you get my drift. If this doesnt answer your question, i must be having one of my 'dense' days again and i shall go and beat myself with a fish until my brain gets running again. |
Quote:
PHP Code:
Anyhow, let's say you have just a normal mysql class in database.php In index.php you need to include the database.php in order to create an instance of that object: PHP Code:
You with me so far? And now, I have this factory, in a file called DB.php And each of the database classes is in DIFFERENT files: DBmysql.php DBmssql.php DBoracle.php But in my DB.php, I haven't included them, because I only want to include the one I will use for my instance of the object. So, if I have PHP Code:
PHP Code:
And that's where my question comes in. How will I include it, like I said before? PHP Code:
|
ah i think i get what ur saying (finally i didnt find a fish but managed to find a source of caffine)
yes you could include it like: PHP Code:
PHP Code:
i hope that helps :) |
Yea, but can I place the function __autoload in the class DB.php where my "DB factory" is?? And how would I do that??
|
PHP Code:
|
Ah, thanks!! Now I understand :D
|
No problem m8, glad to be of service :)
|
| All times are GMT. The time now is 05:13 AM. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0