Ho trovato una soluzione (in PHP) per un problema e mi sto chiedendo se si tratta di un Design Pattern nominato, e se è una buona pratica.
Ho una classe di raccolta e una classe di oggetti. La classe di raccolta è l'unica autorizzata a impostare i dati protetti della classe dell'articolo, oltre alla classe stessa.
L'ho fatto dando alla classe item
un metodo che considera l'oggetto collection
come argomento. L'oggetto item
imposta quindi i suoi dati con gli oggetti collection
.
In questo modo, possiamo dire:
$item_coll = new collection();
$item_coll->load($criterion1, $criterion2);
Poiché la raccolta implementa IteratorAggregate, possiamo anche fare questo:
foreach($item_coll as $item) {
echo 'Item name is ' . $item->getName();
}
Anche dopo aver caricato una raccolta, puoi ottenere una sottocartella utilizzando il metodo getBy($property,$value)
:
$sub_collection = $item_coll->getBy('color','green'); // new collection object with green items
E ora ho una collezione di item
oggetti con tutti i loro set di dati.
Ecco le classi (con metodi / proprietà impertinenti non mostrate).
class item {
protected $id; // id from database table
protected $prop1; // properties also from database
protected $prop2;
public function setData(collection $coll, $id) {
$data = $coll->getData($id);
foreach($data as $key=>$value) {
$this->$key = $value
}
return $this;
}
public function getId() {
return $this->id;
}
}
class collection implements IteratorAggregate { // interface for foreach access to $collection
protected $data = array();
protected $collection = array(); // contains 'item' objects
public function getData($id) {
if(array_key_exists($id,$this->data) ) {
return $this->data[$id];
} else return array();
}
public function load(someClass $obj1, someClass2 $obj2) { // arguments not relevant here, they determine the contents of the collection
// based on arguments, data is loaded from database into $this->data;
foreach($rows as $row) { // database data
$this->data[$id] = $row;
$obj = $this->collection[$id] = new item();
$obj->setData($this,$id); // collection object passes itself into item object
}
}
public function html() {//
foreach($this as $obj) {
// loop through collection to create an html table for display
}
}
public function addItem(item $item) { // add already-existing items to collection
if(!array_key_exists($id,$this->collection) ) {
$this->collection[$item->getId()] = $item;
}
}
public function getIterator() { // for IteratorAggregate interface
return new ArrayIterator($this->collection);
}
public function getBy($property,$value) {
$collection = new static(); // new collection created
// loop through $this object and fill $collection with matching item objects
return $collection;
}
public function getById($id) { // get a single item object by its id
if(array_key_exists($id,$this->collection) ) {
return $this->collection[$id];
}
}
}