Я хочу реализовать шаблон проектирования стратегии с помощью php:
interface dummy_function {
public function render();
}
class a implements dummy_function {
public function render() {
echo "class a\n";
// I want to acess x_main::dummy like: echo parent::dummy
}
}
class b implements dummy_function {
public function render() {
echo "class b\n";
// I want to acess x_main::dummy like: echo parent::dummy
}
}
class x_main {
public $dummy = "hello world";
public function setX_Function( dummy_function $funcname ) {
$this->x_function = $funcname;
}
public function render() {
$this->x_function->render();
}
}$test = new x_main();
$test->setX_Function( new a() );
$test->render();
Внутри моих классов я хочу получить доступ к некоторым методам и переменным, определенным в основном классе. К сожалению, «родитель» не работает для доступа к содержимому из класса «x_main» внутри классов реализации.
Я нашел способ дать $ this в качестве параметра для метода «render», например:
class x_main {
[...]
public function render() {
$this->x_function->render( $this );
}
}
class a implements dummy_function {
public function render( $mainclass ) {
echo "class a\n";
echo $mainclass->dummy;
}
}
Следующим способом, которым я тестирую, является установка переменной из класса main непосредственно в реализованную функцию, например:
class x_main {
[ ... ]
public function setX_Function( dummy_function $funcname ) {
$this->x_function = $funcname;
$this->x_function->dummy = $dummy;
}
}
class a implements dummy_function {
public function render() {
echo "class a\n";
echo $this->dummy;
}
}
Оба решения работают, но я чувствую себя немного смущенным, если это лучший способ реализовать мою желаемую идею. Это выглядит как обходной путь, но не как настоящее ОО-программирование.
Я с нетерпением жду ваших идей.
Перефразирование комментариев выше:
Эти два класса никак не связаны, у них определенно нет
родительские отношения. Один объект, содержащий экземпляр другого объекта
не означает, что эти два объекта находятся в каких-либо отношениях с
друг друга. Вам просто нужно явно передать данные в ваш
экземпляр фиктивной функции; например.:public function render(array $data).
Отклик:
В моем первом решении я поместил весь основной класс в качестве параметра
функция рендеринга. Так что это решение, которое будет работать в любом случае. Но
если нет определенно никакой связи между этими двумя объектами I
предпочитаю мое второе решение, устанавливая параметры непосредственно с
$this->x_function->dummy = $dummy;
Извините, что сказал, что вы не правы. Неявная установка свойства для объекта никоим образом не является определенный интерфейс. И я не использую это слово в смысле PHP interface
ключевое слово, я имею в виду это в более широком смысле указание, как два куска кода могут взаимодействовать и взаимодействовать.
Вы проделали хорошую работу по определению и использованию interface
для render()
функция, это значительно уменьшает связывание кода и увеличивает гибкость и тестируемость. Теперь вы снова уничтожаете это с помощью неопределенных и хрупких назначений свойств.
Вам нужно сделать передача данных в render
аспект часть вашего интерфейса спецификации. Например:
interface dummy_function {
public function render(array $data);
}
Или же:
interface dummy_function {
public function setData(array $data);
public function render();
}
Или лучше:
interface DummyData {
/**
* @return string
*/
public function getDummyData();
}
interface DummyRenderer {
public function render(DummyData $data);
}
С этим вы:
string
)render()
может получить доступ к таким данным (он получит DummyData
объект, который имеет getDummyData()
метод)Вам не нужно угадывать, какие имена свойств задействованы или какую структуру имеет переданный объект.
Других решений пока нет …