Я хотел бы получить отзыв о моем подходе к кодированию (т. Е. О том, уместен ли он или можно ли сделать то, что я сделал, возможно, лучшим способом):
Я хотел бы создать интерфейс для документирования того, что конструктор должен иметь определенный формат. Конечно, если интерфейс содержит только конструктор (и я даже удивился, что PHP позволяет вам помещать конструктор в интерфейс), интерфейс не будет иметь никакого эффекта (за исключением, возможно, документации). Кроме того, PHP не обеспечивает соответствие параметров любого вызываемого объекта ни по количеству, ни по типу, и это верно как для функций, так и для методов и конструкторов.
Если вы увидите, как я назвал свои классы, вы поймете, что я пытаюсь сделать (документ, что параметр конструктора должен быть экземпляром мессенджера, слишком плохо, я не мог сделать больше, чтобы обеспечить это). Пожалуйста, дайте мне знать, если мой подход в порядке и могу ли я улучшить его.
class Messenger {
private $message;
function __construct($message = "Hello!") {
$this->message = $message;
}
public function getMessage() {
return $this->message;
}
}
Имея в виду вышеупомянутый простой класс, я хочу создать интерфейс, подобный следующему, но так как мы имеем дело с конструктором PHP, это должно быть бесполезно?
interface MessengerAware {
function __construct($messenger);
}
class MessengerKnower implements MessengerAware {
private $messenger;
function __construct($messenger) {
$this->messenger = $messenger;
}
public function displayMessengerMessage() {
echo $this->messenger->getMessage();
}
}
Затем я хочу применить свой интерфейс в классе под названием Runner
такие как следующее:
class Runner {
private $messengerAware;
function __construct($messengerAware) {
if (!is_a($messengerAware, 'MessengerAware')) {
die("I'm expecting an instance implementing the MessengerAware interface.");
}
$this->messengerAware = $messengerAware;
}
public function run() {
echo "I'm running.\n";
$this->messengerAware->displayMessengerMessage();
}
}
и, наконец, запустите этот код:
$messengerAware = new MessengerKnower(new Messenger());
$runner = new Runner($messengerAware);
$runner->run();
ВЫХОД:
I'm running.
Hello!
Возможно, это невозможно, но проблему можно обойти, используя один (или несколько) заводских методов:
Оставьте это без изменений:
class Messenger {
private $message;
function __construct($message = "Hello!") {
$this->message = $message;
}
public function getMessage() {
return $this->message;
}
}
Эта модификация …
interface MessengerAware {
public static function create($messenger);
public function displayMessengerMessage();
}
и этот…
class MessengerKnower implements MessengerAware {
private $messenger;
public static function create($messenger) {
$messengerKnower = new MessengerKnower();
$messengerKnower->messenger = $messenger;
return $messengerKnower;
}
public function displayMessengerMessage() {
echo $this->messenger->getMessage();
}
}
Оставьте это без изменений …
class Runner {
private $messengerAware;
function __construct($messengerAware) {
if (!is_a($messengerAware, 'MessengerAware')) {
die("I'm expecting an instance implementing the MessengerAware interface.");
}
$this->messengerAware = $messengerAware;
}
public function run() {
echo "I'm running.\n";
$this->messengerAware->displayMessengerMessage();
}
}
Наконец, настройте этот код:
$messengerAware = MessengerKnower::create(new Messenger());
$runner = new Runner($messengerAware);
$runner->run();
ВЫХОД:
I'm running.
Hello!
Других решений пока нет …