У меня есть общий класс Collection, с множеством общедоступных методов getter.
Чтобы получить один элемент из коллекции, вы вызываете get (). Существует также несколько методов, которые возвращают несколько элементов: getMany (), getRange (), getAll (), find (), findAll (), query (), queryAny () и т. Д.
Внутренне все эти методы, возвращающие несколько элементов, имеют цикл, который вызывает метод get (), поскольку они агрегируют отдельные элементы для возврата.
Упрощенный пример:
public function get($key){ return $this->collection[$key]; } public function getMany($keys){ $many = array(); foreach ($keys as $key){ $many[] = $this->get($key); } return $many; }
Проблема возникает, когда я хочу расширить коллекцию таким образом, что я не хочу, чтобы клиент мог получить доступ к одному элементу из коллекции. В принципе, я хочу запретить доступ к методу get ().
Я не могу сделать get () частной или защищенной функцией, потому что она является общедоступной в родительском классе.
Я также не могу переопределить get () таким образом, чтобы сделать его нефункциональным (т. Е. Переопределить его только с возвратом или выбросить исключение), потому что все остальные методы полагаются на get (), и я хочу, чтобы они остаются функциональными.
Я знаю, что могу просто переопределить все методы, которые полагаются на get (), чтобы полагаться на какой-то новый защищенный метод (т.е. getOne ()), но это нарушило бы сухие принципы.
ЧТО Я НЕ ХОЧУ ДЕЛАТЬ:
class DataSet extends Collection{ public function get(){ throw new Exception('get() not implemented in DataSet'); } protected function getOne($key){ return parent::get($key); } public function getMany($keys){ $many = array(); foreach ($keys as $key){ $many[] = $this->getOne($key); } return $many; } }
Если бы я сделал это, мне пришлось бы переопределить полдюжины методов (некоторые из которых довольно сложны), и они будут отличаться от метода родительского класса несколькими символами.
Итак … какие у меня есть другие варианты? Существуют ли разные средства для того же конца …?
Что вы можете сделать, так это сделать защищенный метод say _get
и это может быть то, что вызовут все методы внутри. Затем вы можете разоблачить метод get
на всех классах, которым нужен доступ, и просто попросите его вызвать _get
.