Re: [PHP] Suggestions for class design
Hi Chris, nice thread, good questions - nice to see some real programming theory being discussed - does us all some good :-) here is my take, hth: Chris W. Parker wrote: Anas Mughal mailto:[EMAIL PROTECTED] on Monday, September 19, 2005 4:02 PM said: The simplest way to solve this problem is as follows: - Have your Customer class hold only attributes for a customer. This class would only have getter and setter methods. In the Java world, this is referred to as a JavaBean. - Then, have a DAO class that does your data access functions. Here is a sample DAO class: [snip] Ahh.. I guess this is the same thing that Michael Sims suggested? class CustomerDAO { function getCustomer(..) { ... //return a customer } So I return a Customer object that has the set and get methods? And does that mean I do the following? -set_first_name() -set_last_name() -set_address_1() -set_address_2() -set_address_3() -set_city() -set_state() me, I have 'data object' that are subclasses of a 'peer' object, the 'peer' class has all the methods for data handling e.g. Persistent::submit() (update and insert are handled/determined internally) Persistent::get() Persistent::find() Persistent::findRange() etc.. the 'data object's have definitions that stipulate 'field' objects for each field in the database (usually a 1 to 1 relationship but not always - for instance there is a VectorField for 1 to many stuff, and an AssocField for many to many stuff). if I have a Customer class I can do something _like_: $cust = Persistent::get('Customer', array('CONTACT_ID' = $id)); $cust-firstname = 'Bob'; $cust-lastname = 'Builder'; $cust-submit(); the 'peer' class has __get() and __set() methods that find the requested 'field' object and return or set its value e.g. (very simplified) class Persistent { function __get($name) { if (isset($this-fields[$name])) { return $this-fields[$name]-getValue(); } throw new Exception(field '$name' does not exist in this (.get_class($this).) object!); } } maybe that gives you an idea about how to avoid constantly writing practically the same getter/setter methods over and over... and also how to avoid writing practically identical collection getter functions/methods (how much different will you getCustomers() method be from your getProducts() method ... in general anyway ... there are always exceptions to the rule! :) etc. Or is there a better way to handle it? function getCustomers(..) { ... // return a collection of customers } How do I return a collection of customers? Thanks, Chris. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Suggestions for class design
Sorry I've been so quiet on this topic since I started it but I've basically been overwhelmed with information! :) I was hoping the answer(s) would be a lot more plain and simple than it(they) has been so I could get to implementing some things right away. But I'm afraid it's going to take me longer than I'd hoped. It would be great if someone could contribute some more fleshed out and basic code, but I know we're probably all busy. As I have spare time I'll go over again (and again) the messages in this topic as well as Propel and Metastorage. Thanks, Chris. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Suggestions for class design
[snip] Where I get tripped up is when I realize I'll need to at some point get more than one customer at a time and thus I want to add a method called 'get_customers()'. [/snip] I know that you didn't ask for this, but the point needs discussing given your assertion above. Why, at any point, would you need to get more than one customer? One answer is that all customers or a group of customers will need to be updated/edited with the same information. Therefore you need a seperate class for multiple customers which could then be extended by group. A group of customers is a seperate object. Make sense? -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Suggestions for class design
Jay Blanchard mailto:[EMAIL PROTECTED] on Monday, September 19, 2005 10:40 AM said: [snip] Where I get tripped up is when I realize I'll need to at some point get more than one customer at a time and thus I want to add a method called 'get_customers()'. [/snip] Why, at any point, would you need to get more than one customer? Good question. When I need more than one customer is when I'm displaying them all on an administration page. Maybe a better example class would be Products. One individual product is displayed on the product's detail page, but in the search results I'd normally be using the same Product class to display all the results which forces me to create a 'get_products()' method. One answer is that all customers or a group of customers will need to be updated/edited with the same information. Therefore you need a seperate class for multiple customers which could then be extended by group. A group of customers is a seperate object. Make sense? Well, yes I think it does, but what I'm missing is how this new object interacts with the original one if it does at all. And what would I call it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :) Do I extend the Customer class or is it a stand alone class? Thanks, Chris. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Suggestions for class design
[snip] Well, yes I think it does, but what I'm missing is how this new object interacts with the original one if it does at all. And what would I call it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :) Do I extend the Customer class or is it a stand alone class? [/snip] I think that it should be a stand alone class. The Customers class could instantiate the needed number of Customer objects and the methods of the Customers class could affect each Customer object. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Suggestions for class design
Jay Blanchard wrote: [snip] Well, yes I think it does, but what I'm missing is how this new object interacts with the original one if it does at all. And what would I call it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :) Do I extend the Customer class or is it a stand alone class? [/snip] I think that it should be a stand alone class. The Customers class could instantiate the needed number of Customer objects and the methods of the Customers class could affect each Customer object. +1 for this idea, it is a method I have used on countless projects and works very well. Mikey -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Suggestions for class design
Jay Blanchard mailto:[EMAIL PROTECTED] on Monday, September 19, 2005 10:53 AM said: I think that it should be a stand alone class. The Customers class could instantiate the needed number of Customer objects and the methods of the Customers class could affect each Customer object. I'm stuck on how I convert 'SELECT id, name FROM customers WHERE id nn' into the needed number of Customer objects. Here's an attempt: class Customers { var $customers = array(); function get_customers($sql) { // instantiate db object $db = new DB::singleton(); // get results of $sql $results = $db-execute($sql); foreach($results as $v) { // instantiate one Customer object $tmp = new Customer; // populate it with data $tmp-id = $v['id']; $tmp-name = $v['name']; // store it in array $this-customers[] = $tmp; } } function delete_customers() { // loop through array of customer objects ... foreach($this-customers as $customer_obj) { // ... deleting each customer one at a time $customer_obj-delete_customer(); } } } Thanks, Chris. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Suggestions for class design
On Mon, 2005-09-19 at 14:00, Mikey wrote: Jay Blanchard wrote: [snip] Well, yes I think it does, but what I'm missing is how this new object interacts with the original one if it does at all. And what would I call it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :) Do I extend the Customer class or is it a stand alone class? [/snip] I think that it should be a stand alone class. The Customers class could instantiate the needed number of Customer objects and the methods of the Customers class could affect each Customer object. +1 for this idea, it is a method I have used on countless projects and works very well. Mikey -- .. | InterJinn Application Framework - http://www.interjinn.com | :: | An application and templating framework for PHP. Boasting | | a powerful, scalable system for accessing system services | | such as forms, properties, sessions, and caches. InterJinn | | also provides an extremely flexible architecture for | | creating re-usable components quickly and easily. | `' -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Suggestions for class design
Chris W. Parker wrote: snip class Customer { var $id; var $name; snip snip function get_customer() { snip snip $this-name = $customer['name']; } snip Where I get tripped up is when I realize I'll need to at some point get more than one customer at a time and thus I want to add a method called 'get_customers()'. snip Hi Chris Assuming that you have some procedural code, could you not create an array of Customer objects? I am not sure what argument would be passed to the get_customer function as you do not have an argument in the function definition, but if it was perhaps the customer name, you coud have something like : /*Procedural code*/ $get_customer_names = 'SELECT ... FROM WHERE customer ADDRESS LIKE '; $customer_name_result_set = $db_connection-query($get_customer_names); for($i=0; $i $customer_name_result_set-num_rows; $i++) { $customer_name_result_record = $customer_name_result_set-fetch_row(); $customers[$i] = new Customer; $customers[$i]-get_customer($customer_name_result_record[0]); } That's how I would do it, at any rate (which is probably no recommendation ;) ). Regards Rory -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Suggestions for class design
Chris W. Parker wrote: Let's take for example a class called 'Customer' that (obviously) manipulates customers in the database. Here is a very basic Customer class. (Data validation and the like are left out for brevity.) [snip] Where I get tripped up is when I realize I'll need to at some point get more than one customer at a time and thus I want to add a method called 'get_customers()'. Since an object should be a single instance of something (e.g. ONE customer) how do I justify adding the method 'get_customers()'? Or better yer, how do I properly add a method like that? (A method where instead of using a SQL statement to return ONE customer's data I instead return a record set with more than one customer.) [snip] Basically you're implementing DAO's (Data Access Objects), similar to what an ORM (Object Relational Mapper) tool would do for you. There are lots of different approaches for implementing DAO's, but personally I prefer to use a DAO class that represents one entity in my database (in your example, the Customer), and then have another separate class which is responsible for data operations on my DAO (the peer class). (This is the approach that many existing ORM tools use, both in the PHP and Java worlds.) In other words, Customer is only used to access the data that has been retrieved, but Customer itself doesn't have any methods for retrieving, updating, deleting, or saving. The CustomerPeer class handles all the data operations on Customer. If you want a particular Customer instance, you ask the peer to retrieve it for you, and it returns the appropriate object. If you want to save changes to a Customer, you retrieve the right instance, set its attributes, then give it back to the peer class which handles the database interaction. So, the Customer class is completely ignorant of the database, and is only concerned with giving you access to the data that is related to that Customer (and any other app specific methods that it makes since for the Customer class to handle). The advantage to using this approach is that you can easily have your peer class return an array of Customer objects, each one representing only one customer. Chris W. Parker wrote: Well, yes I think it does, but what I'm missing is how this new object interacts with the original one if it does at all. And what would I call it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :) Do I extend the Customer class or is it a stand alone class? As stated, I wouldn't recommend creating a new class to hold the Customers. Just use a normal PHP array of Customer objects. In your spare time, take a look at Propel (http://propel.phpdb.org/), an ORM for PHP5. I wouldn't suggest trying to introduce something like this in the middle of an existing project, but consider toying around with it for a future project. I used this for my last application with great success. It used 20 DAO's, similar to your Customer object, and Propel saved me a lot of tedious work in implementing all of the data-related methods+getters/setters for these 20 objects. If you have any questions about it feel free to drop me a line or check out the Propel mailing list which is very helpful. HTH... -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP] Suggestions for class design
Michael Sims mailto:[EMAIL PROTECTED] on Monday, September 19, 2005 12:04 PM said: Basically you're implementing DAO's (Data Access Objects), similar to what an ORM (Object Relational Mapper) tool would do for you. [snip] Thanks for the info, and I'll check out the Propel site a little later, but this is basically what I was saying I don't understand. I'd appreciate some actual code recommendations as I have a hard time understanding the abstract descriptions of how objects should work and be designed. Chris. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Suggestions for class design
Chris W. Parker [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Jay Blanchard mailto:[EMAIL PROTECTED] on Monday, September 19, 2005 10:40 AM said: [snip] Where I get tripped up is when I realize I'll need to at some point get more than one customer at a time and thus I want to add a method called 'get_customers()'. [/snip] Why, at any point, would you need to get more than one customer? Good question. When I need more than one customer is when I'm displaying them all on an administration page. Maybe a better example class would be Products. One individual product is displayed on the product's detail page, but in the search results I'd normally be using the same Product class to display all the results which forces me to create a 'get_products()' method. --- The signs don't seem to show up on this reply, sorry. Anyway, I have often found the need to make an object and a collection of the same kind of objects. A Customers class containing Customer items, Products and Product. Usually, the collections all look quite the same, they have the Add (which gives me a brand new initialized item object) , Find (which returns another instance of the Customers class, this with a subset of the whole collection), Get (returns and individual item based on a key), Delete (you cannot ask an object to delete itself while you are having a reference to it), Update (call the Update method of the modified items), then, if the language allows, a means to iterate over it and posibly some sort alternatives. Beware, though, that this sounds nice and proper except when the collection starts loading and taking up memory. Then you can handle several strategies, the first is 'load as you go' or 'on demand'. If nobody asks for it, don't load it. Then, you can load the properties on demand as well. You might only load the primary keys first, to be able to enumerate them and then load the rest of the properties when the get_() function is called. Actually, from an SQL standpoint, it is better to subdivide your fields into those which are used most often, and have them loaded as a group, then several sets of specific fields, groups that usually go together (like an address record, if the street is accessed, there is a good change that the zip will also be accessed, so, load them both when either one is read. Several internal flags should keep track of which set of fields are loaded for each set. Sounds terrible? Yes, it is. It is much faster to rely on the SQL server to handle most of the job of these collections. If you are just sequentially fetching records to show on a listing, it is easier to let them come from the database, a record at a time, and send it right to the client, using and reusing the memory of the resultset over and over. Much faster than loading them in either an array or a collection and then showing them from there. Specially if using them in an environment like a web server where the connection is not persistent and whatever gets loaded in response to a page request gets lost after that is handled. They are much more usefull in batch processes, where you can hold of to that information for quite a while, and it is worth to have it handy. But we don't do that kind of processes any longer these days. Satyam One answer is that all customers or a group of customers will need to be updated/edited with the same information. Therefore you need a seperate class for multiple customers which could then be extended by group. A group of customers is a seperate object. Make sense? Well, yes I think it does, but what I'm missing is how this new object interacts with the original one if it does at all. And what would I call it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :) Do I extend the Customer class or is it a stand alone class? Thanks, Chris. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Suggestions for class design
From what I understand is you need a data objects class. Use a generic class such as PEAR's DB_DataObject (http://pear.php.net/package/DB_DataObject). All you have to do is give the table name and the class for example would be in our case DB_DataObject_Customer And then querying the table would be in a line such as [code] $customer_data=new DB_DataObject_Customer(); $customer-get, -insert,-find, -update and the other goodies given that you supply the right parameters. [/code] HTH.
Re: [PHP] Suggestions for class design
The simplest way to solve this problem is as follows: - Have your Customer class hold only attributes for a customer. This class would only have getter and setter methods. In the Java world, this is referred to as a JavaBean. - Then, have a DAO class that does your data access functions. Here is a sample DAO class: class CustomerDAO { function getCustomer(..) { ... //return a customer } function getCustomers(..) { ... // return a collection of customers } function saveCustomer(..) { ... } } Hope this helps. -- Anas Mughal On 9/19/05, Chris W. Parker [EMAIL PROTECTED] wrote: Hello, Every time I write some classes I always come across the same fundamental problem that I haven't figured out how to solve/approach yet. I'm not exactly sure how to put it into words simply but here goes... Let's take for example a class called 'Customer' that (obviously) manipulates customers in the database. Here is a very basic Customer class. (Data validation and the like are left out for brevity.) class Customer { var $id; var $name; function add_customer() { // create sql statement $sql = INSERT INTO ...; // create db connection $db = DB::singleton(); // execute SQL $db-execute($sql); } function delete_customer() { // create sql statement $sql = DELETE FROM ...; // create db connection $db = DB::singleton(); // execute SQL $db-execute($sql); } function get_customer() { // create sql statement $sql = SELECT ... FROM ...; // create db connection $db = DB::singleton(); // execute SQL $customer = $db-execute($sql); // populate object variables $this-id = $customer['id']; $this-name = $customer['name']; } } (Unless I've already got some major design flaws I think we should be good to go.) Where I get tripped up is when I realize I'll need to at some point get more than one customer at a time and thus I want to add a method called 'get_customers()'. Since an object should be a single instance of something (e.g. ONE customer) how do I justify adding the method 'get_customers()'? Or better yer, how do I properly add a method like that? (A method where instead of using a SQL statement to return ONE customer's data I instead return a record set with more than one customer.) The class in its current state can't handle data like that so I have to then rethink the design and a new object variable called $customers where I store the record set that is in return accessed directly by the calling page itself. With the way I'm working with these objects now they seem less like objects and more like an organized collection of functions. I'd appreciate some actual code recommendations as I have a hard time understanding the abstract descriptions of how objects should work and be designed. Thanks, Chris. Thanks! Chris. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php -- Anas Mughal