Re: Question about OO design

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Chris W. Parker wrote:
> Hello,
>  
> I'm working on a project now and I'd like to get some feedback on how to
> implement a proper class (or two).
> 
> This is an application that records an employee's used vacation time.
> There are two tables: (1) events, (2) users.
> 
> Users:
> 
> id (int)
> name (varchar)
> email (varchar)
> balance (mediumint, stored in seconds) // this is the balance for
>                                        // the user after all events
>                                        // have been accounted for.
> accrual (smallint, stored in seconds)
> is_manager (bool)
> 
> Events:
> 
> id (int)
> uid (int, users.id)
> date (date)
> duration (smallint, stored in seconds)
> balance (smallint, stored in seconds) // this is the balance for
>                                       // the user at the time the
>                                       // event was added.
> created (datetime)
> 
> 
> Currently I have just one class called User that looks like this:
> 
> 
> (I'm dealing with PHP4.)
> 
> class User
> {
> 	var id;
> 	var name;
> 	var email;
> 	var balance;
> 	var accrual;
> 	var is_manager;
> 
> 	function User($user_id)
> 	{
> 		$this->id = $user_id;
> 		$this->name = get_name();
> 		// ...
> 		$this->accrual = get_accrual();
> 	}
> 
> 	function get_name()
> 	{
> 		// get name from db
> 		$sql = "...";
> 
> 		$db =& DB::singleton();
> 		$db->execute($sql);

you probably only want one DB call to
populate the User object with all the relevant
user data at the point where the object is created.

function User($user_id)
{
	// check the user id properly?

	// see the getEmployee() example below for the
	// reason for the array usage
	if (is_array($user_id)) {
		$this->id = $user_id['id'];
		$this->load($user_id);	
	} else {
		$this->id = $user_id;
		$this->load();
	}
}

function load($data = null)
{
	if (!is_array($data) || empty($data)) {
		// get user data from db
		$sql = "SELECT * FROM users WHERE id={$this->id}";

		// error checking?
		$db =& DB::singleton();
		$db->execute($sql);
		$data = $db->getRow();
	}

	$this->name 	= $data['name'];
	$this->accrual 	= $data['accrual'];
	$this->email 	= $data['email'];
	/// etc
}	

> 
> 	function get_email()
> 	function get_accrual()
> 	function is_manager()
> 	{
> 		// same as above more or less
> 	}
> 
> 	function get_events()
> 	{
> 		// this function gets all the events for
> 		// the current users and returns them
> 		// as an array.
> 	}
> 
> 	function add_event()
> 	{
> 		// this function adds a single event for
> 		// the current user. it also recalculates
> 		// the 'balance' for each event because
> 		// of data display requirements.
> 	}
> 
> 	function del_event($event_id)
> 	{
> 		// delete an event from the current user's
> 		// events list based on $event_id.
> 	}
> }
> 
> 
> As I started to write this and use it I get the feeling that there
> should also be an Event class that is extended by the User class. Reason

if you use an Event class then it should just represent an Event (and
a User object would [probably] contain an array of Event objects).
AFAICT there is no good reason to have Event extend User.

> being that each User object is a reference to the currently logged in
> user, not anyone else. 

the User class is merely a representation of *a* user - you can
use an instance for the currently logged in user, but that doesn't stop you
from using the same class to model the collection of users that fall under
a given manager.

> But if you're a manager you have the
> responsibility to approve/deny and/or add/delete events for your
> employees.

// you might need to f around with returning references here,
// (I can never quite get that right without a bit of trial and error in php4)
function getEmployees()
{	
	// consider caching the result?
	$emps = array();
	if ($this->is_manager) {

		// get user data from db
		$sql = "SELECT * FROM users WHERE manager_id={$this->id}";

		// error checking?
		$db =& DB::singleton();
		$db->execute($sql);
		while ($data = $db->getRow())
			$emps[] =& new User($data);
	}

	return $emps;
}

> 
> But with that in mind I've gone from a class that handles the currently
> logged in user to one that handles the currently logged in user plus any
> number of other users.
> 
> I guess I'm thinking of this in the same terms as db normalization. Ex:
> I could add an extra price_level column to my products table each time I
> need a new pricing level but it's probably better to create a separate
> table called products_prices. It's slightly more complicated but it
> would allow me to have as many pricing levels as I want without
> modifying my databse or code.
> 
> 
> I'd appreciate any kind of feedback on this. If I haven't been clear
> with something please let me know.
> 
> 
> 
> Thanks,
> Chris.
> 

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux