I want to separate data from source of the data. One class for database interaction and class for data manipulation. But my approach violates LSP: preconditions cannot be strengthened in a subtype and raises strict error: Declaration of DataRepositoryItem::save() should be compatible with DataRepositoryAbstract::save(DataAbstract $data)
class DataAbstract {
}
class DataItem extends DataAbstract {
}
class DataObject extends DataAbstract {
}
abstract class DataRepositoryAbstract {
/** @return DataAbstract */
public function loadOne(){}
/** @return DataAbstract[] */
public function loadAll(){}
public function save(DataAbstract $data){}
}
class DataRepositoryItem extends DataRepositoryAbstract {
/** @return DataItem */
public function loadOne(){}
/** @return DataItem[] */
public function loadAll(){}
public function save(DataItem $data) {} // <--- violates LSP, how to avoid it?
}
class DataRepositoryObject extends DataRepositoryAbstract {
/** @return DataObject */
public function loadOne(){}
/** @return DataObject[] */
public function loadAll(){}
public function save(DataObject $data) {} // <--- violates LSP, how to avoid it?
}
How to recombine the code to fit LSP?
Update: Ok, I could rewrite methods.
class DataRepositoryItem extends DataRepositoryAbstract {
/** @return DataItem */
public function loadOne(){}
/** @return DataItem[] */
public function loadAll(){}
public function save(DataAbstract $data) {
assert($date instanceof DataItem);
//...
}
}
Works in PHP, but still violates LSP. How to avoid it?
from Avoiding of violating LSP
No comments:
Post a Comment