Jump to content

Recommended Posts

I don't agree that UMLs are a waste of time, but I would appreciate a little guidance as to where to start with this one.  It's pretty large and so it's hard to make sense of everything.  So, I think the first thing you could do is break it up into three separate UMLs one for the view, model, and controller.  That way we could consume them individually and come back to the entire UML with greater understanding.

 

With that said I did take a look and it seems you're starting a large project.  I say this looking at your domain model, which has most of the usual suspects.  May I ask what data wrapper you plan to use?  If you're going to be implementing one from scratch you may be interested in putting your effort together with mine and my partner's, as we're currently developing an ORM/persistance layer in PHP. 

 

I like the registry you've spec'd but I wonder what is the purpose of the sleep and wakeup methods?  At least I don't understand there purpose so far as you're running a single thread at a time.  If you imagine running multiple threads (is that even possible in PHP?) then I see the reason why they've been included.

 

If I find time later I'll say some more about the view and controller

I don't agree that UMLs are a waste of time, but I would appreciate a little guidance as to where to start with this one.  It's pretty large and so it's hard to make sense of everything.  So, I think the first thing you could do is break it up into three separate UMLs one for the view, model, and controller.  That way we could consume them individually and come back to the entire UML with greater understanding.

 

I've considered that (and done it), but this time I decided I wanted the whole picture. A package diagram wouldn't give the me the level of detail I'm wanting at this time. I can see how the size and level of detail can be confusing. Once I have decided on the final design of a package, I'll put it into it's own file, and have it represented by a package in this one. The Controller is the first probable candidate for this.

 

It's not complete yet, for example I haven't included a View reference in the Tokens. This because I haven't spent much thought on the View yet.

 

The idea for the Controller is to provide a rigid frame for all application commands. Every single command is encapsulated in a Command object, producing a status, with which the Application Controller decides which Token it needs next, based on XML configuration, assisted by Controller_Factory. References to the model are provided through a Context object, which is reused for multiple Commands. I'm planning on a Transaction Manager, so Context objects would only provide the Commands with the actual domain objects. The Context objects would be responsible for starting/resuming transactions. I still have some decisions to make regarding input during a transaction spanning multiple requests.

 

So basically a client developer would make concrete Context and Command classes, provide them with appropriate status codes, and create an XML configuration file to dictate application flow. Controller_Factory would use a serialized Token cache to avoid endless XML parsing.

 

I like the registry you've spec'd but I wonder what is the purpose of the sleep and wakeup methods?  At least I don't understand there purpose so far as you're running a single thread at a time.  If you imagine running multiple threads (is that even possible in PHP?) then I see the reason why they've been included.

 

I've abstracted __sleep() into the DomainObject abstract because I'm lazy.  ;)

 

class Backbone_Tools {

/**
 * Returns array of an objects property names, convenient for __sleep()
 *
 * @param object $obj
 * @return array
 */
public static function getObjectPropNames($obj){
	$refl = new ReflectionObject($obj);
	$propNames = array();
	foreach ($refl->getProperties() as $reflProp){
		$propNames[] = $reflProp->getName();
	}
	return $propNames;
}

 

The Application Registry will use serialization, a simple Serialized LOB. Same goes for the Session Registry. And no, PHP doesn't have threading support, closest one can come is utilizing the Process Control functions. But that isn't available on most shared hosts, so I'm leaving them well alone. Concurrency is always an issue in web applications, not just multi-threaded ones.

 

With that said I did take a look and it seems you're starting a large project.  I say this looking at your domain model, which has most of the usual suspects.  May I ask what data wrapper you plan to use?  If you're going to be implementing one from scratch you may be interested in putting your effort together with mine and my partner's, as we're currently developing an ORM/persistance layer in PHP.

 

I still have a lot of thinking to do on the Data Layer. Only thing I've really decided on is that I want to use Unit of Work Controller [PoEAA: 187]. I've named it Data_Controller, because it sounds a little more catchy  :P. I don't want a client developer to worry about marking objects dirty etc, as would be required with caller or object registration. Sure it's a little more expensive, but I'm sure I can minimize the cost. I still need a lot more thought on Data Mapping, in particular Foreign Key Mapping.

 

I'd be interested in trading thoughts on ORM, and joining efforts sounds perfect to me, if we can come to an agreement on the approach. Send me a PM, we can talk a little about this in private.

 

Finally, don't bother with the View for now, as I said, I haven't really spent any thought on it. In fact it's just something very old I reverse engineered, it defies the MVC paradigm as in it's current state it would require Command objects to register updates.

I can't seem to tell whether the private messaging system is working for me.  At the least my outbox is mysteriously empty, and my inbox has nothing after 2006 in it... So let me just give you the link to the project here, and you can find my email either on that page (gmail account) or through the source code.  The project is being hosted here:

 

http://code.google.com/p/junction/

  • 3 weeks later...

Ok, so this project is coming along, albeit slowly. More slowly than I'd like in any case. A Template View is in place, the application controller and token forwards, view updates and forwards are all in working order.

 

Next is arguably the most vital part of the framework: the Data Layer. I did have a vision of how it should work, but I still had a lot of unanswered questions, simply coding away wasn't going to change that. So I translated this vision into a sequence diagram, illustrating an update within a transaction... Comments welcome as always.

 

[attachment deleted by admin]

I've run into an unconvienence...

 

In order for the Data Controller to use the right Data Mapper to load an object I need the name of the class, as well as the id of the object to be loaded from store. I use a simple name based mapping (from the data controller):

 

	
public function load($class, $id){
	$mapper = $this->getDomainMapper($class);
	$object = $mapper->load($id);
	$this->referenceMap[$id] = clone $object;
	return $object;
}	
            private function getDomainMapper($domain){
	if($domain instanceof Backbone_Data_Domain_Object){
		$domain = get_class($domain);
	}
		elseif(!is_string($domain) || !class_exists($domain, true)) {
			throw new Backbone_Data_Controller_Exception('Invalid argument passed to Backbone_Data_Controller::getDomainMapper');		
	}
	$mapperClass = $domain.self::$mapperSuffix;
	if(!isset(self::$dataMappers[$mapperClass])){
		self::$dataMappers[$mapperClass] = new $mapperClass;
	}
	return self::$dataMappers[$mapperClass];
}

 

This framework is aimed at easy development, and I want the client classes as carefree as possible. Thus, when a concrete Command class requests an object from a transaction, I don't want it to have to include the name of the class of the object it requests. Which isn't a problem as long as the object is already in the transaction, but becomes a problem when it needs to be loaded from store:

 

	public function get($id){
	if(!isset($this->domainMap[$id])){
		$this->domainMap[$id] = $this->dataController->load($id);
	}
	return $this->domainMap[$id];
}

 

$this->dataController->load($id) will not work without the name of the Domain Object's class to map it to the right Mapper (no pun intended).

 

Any bright ideas?

Now that I think about it, I don't think there really is a way around that... One can't instantiate an object without a the name of it's class, naturally..  :P Hahahahaha....

 

So I guess Command classes will have to settle for something like

 

$object = $this->transaction->get('Some_Domain_Class', 'someId');

 

Which isn't really much more hassle than

 

$object = new Some_Domain_Class('someId');

 

And definitely more carefree than

 

if(!$this->transaction->get('someId')){
       $object = new Some_Domain_Class('someId');
       $this->transaction->set($object);
}

 

 

I'm confusing two different things here:

 

1. Constructing an object in store

 

$object = $this->transaction->get('Some_Domain_Class', 'someId');

 

2. Constructing a completely new object (to be put in store, IF the transaction commits)

 

if(!$this->transaction->get('someId')){
       $object = new Some_Domain_Class('someId');
       $this->transaction->set($object);
}

 

The second scenario needs simplification. I'll come up with something, I think.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.