Unit of Work pattern, getters, setters and contracts (PHP)
I'm not sure if the title is the best way to describe this question.
This book - http://apress.com/book/view/9781590599099 - illustrates an implementation of the Unit of Work pattern. It goes a little something like this.
class UoW(){
private array $dirty;
private array $clean;
private array $new;
private array $delete;
public static function markClean(Entity_Class $Object){
//remove the class from any of the other arrays, add it to the clean array
}
public static function markDirty(Entity_Class $Object){
//remove the class from any of the other arrays, add it to the dirty array
}
public static function markNew(Entity_Class $Object){
//add blank entity classes to the new array
}
public static function markDelete(Entity_Class $Object){
//remove the class reference from other arrays, mark for deletion
}
public function commit(){
//perform all queued operations, move all objects into new array, remove any deleted objects
}
}
class MyMapper(){
public function setName($value){
$this->name = $value;
UoW::markDirty($this);//here's where the problem is
}
}
(Ignoring issues of static calls and dependencies for a moment)
The author notes that this implementation require开发者_如何学Pythons the coder to insert the relevant UoW marking methods, and that this elective honouring of the pattern can lead to errors. Now, taking on board the pros and cons of concrete accessors, you could perhaps automate the UoW invocation like this:
public function __set($key,$value){
//check to see if this is valid property for this class
//assuming the class has an array defining allowed properties
if(property_exists($this,$key)){
$this->$key = $value;
UoW::markDirty($this);
/*
* or alternatively use an observer relationship
* i.e. $this->notify();
* assuming the UoW has been attached prior to this operation
*/
}
}
So, my question is, how would you go about guaranteeing the appropriate UoW method was called when setting properties on a Domain Object?
The best approach I've found is to declare the properties "protected" and then use PHPDoc comments to "expose" them as public properties. Something like:
/**
* @property string $prop
*/
class Foo extends UoW {
protected $prop = "foo";
public function __set($name, $value) {
if (property_exists($this, $name)) {
$this->$name = $value;
$this->markDirty();
}
}
}
This will cause your IDE and most tools to pick up that Foo->prop is a property, while ensuring the dirty mark gets set.
精彩评论