#php #design-patterns #interface
#php #шаблоны проектирования #интерфейс
Вопрос:
Это первый вопрос, который я задаю многим другим в будущем.
Кто-то здесь может назвать меня сумасшедшим, потому что я следую упомянутой книге в названии вопроса, используя PHP-OO.
В первой главе авторы представляют простой проект под названием «SimUDuck», и, хотя я воспроизвел то же самое на Java, мне было интересно воспроизвести то же самое с помощью PHP.
В конце проект SimUDuck создает два (2) интерфейса (FlyBehavior и QuackBehavior), более пяти (5) классов, реализующих эти интерфейсы (например, FlyWithWings(), Quack() и т.д.), абстрактный класс с именем Duck и три (3) или четыре (4) класса разных видов уток, расширяющих Duck (Mallard, HeadRedDuck, RubberDuck и т.д.), Просто чтобы продемонстрировать, насколько важно программировать для интерфейса.
Для имитации среды Java main method я создал класс PHP под названием MiniDuckSimulator, включающий функцию ‘public static function main()’ и в тот же скрипт я добавил «MiniDuckSimulator::main();». Скрипт работает без ошибок.
Интригующая проблема заключается в том, что без вызова какого-либо метода, реализованного QuackBehavior::quack(), echo ‘Quack!появляется quack!’. Те, кто читал эту книгу, знают, о чем я говорю.
Примечание: Ниже приведена определенная часть скрипта:
interface FlyBehavior {
public function fly();
}
interface QuackBehavior {
public function quack();
}
include_once 'FlyBehavior.php';
class FlyWithWings implements FlyBehavior {
public function fly() {
echo 'I'm flying!<br />';
}
}
include_once 'QuackBehavior.php';
class Quack implements QuackBehavior {
public function quack() {
echo 'Quack!<br />';
}
}
abstract class Duck {
protected $flyBehavior;
protected $quackBehavior;
function __construct() {
}
public function performFly(){
$this->flyBehavior->fly();
}
public function performQuack(){
$this->quackBehavior->quack();
}
public function setFlyBehavior($flyBehavior){
$this->flyBehavior = $flyBehavior;
}
public function swim(){
echo "All the ducks float, including the decoy!<br />";
}
}
include_once 'Duck.php';
include_once 'FlyWithWings.php';
include_once 'Quack.php';
class Mallard extends Duck {
function __construct() {
$this->flyBehavior = new FlyWithWings();
$this->quackBehavior = new Quack();
}
}
class MiniDuckSimulator {
public static function main(){
$mallard = new Mallard();
$mallard->performFly();
}
}
MiniDuckSimulator::main();
Заранее спасибо.
Удачно.
Комментарии:
1. У меня болят глаза при чтении текста:-S
2. Извините за это. Я бы сделал это коротким, но пропустил бы некоторую важную информацию для тех, кто заинтересован помочь мне.
3. Двойное «кряканье» совершенно бесполезно. Это может быть один и тот же метод, вызванный дважды, или метод и родительский класс. Я бы добавил немного текста вроде «quack-rubber» и «quack mallard» и т.д.
4. Это лучше???? Теперь о «фрагментах кода», это было бы невозможно, потому что это примерно 10 разных файлов. Что бы я сделал, так это прикрепил эти файлы куда-нибудь.
5. Один из наших коллег беллоу (ник Мачек) ответил на вопрос. Проблема заключалась в том, что класс Quack имел метод quack(), и, поскольку PHP будет обрабатывать любой метод с тем же именем, что и класс, как конструктор класса, когда я вызываю «$mallard = new Quack()», содержимое метода quack() будет выполнено. То, что я сделал, было простым… измените имя класса на NormalClass, вот и все.
Ответ №1:
Причина, по которой вы видите Quack!<br />
вывод, заключается в следующем:
class Quack implements QuackBehavior {
public function quack() {
echo 'Quack!<br />';
}
}
Вот ваша проблема: если вы просто запустите new Quack();
quack()
метод, он автоматически выполняется php как конструктор, потому что у него то же имя, что и у вашего класса. — Я вижу, вы ссылались на Java в своем вопросе, так что это не должно быть для вас чуждой концепцией.
new Quack(); // => Quack!<br />
Потенциально лучший способ
<?php
interface CanFly {
public function fly();
}
interface CanQuack {
public function quack();
}
abstract class Duck implements CanFly, CanQuack {
protected $color = "DEFAULT"
public function fly(){
echo "I'm flying with my {$this->color} wingsn";
}
public function quack(){
echo "I'm quackingn";
}
public function swim(){
echo "I'm swimmingn";
}
}
class Mallard extends Duck {
public function __construct(){
$this->color = "green";
}
public function quack(){
echo "My quack sounds more like a honkn";
}
}
$m = new Mallard();
$m->fly();
$m->quack();
$m->swim();
?>
Вывод
I'm flying with my green wings
My quack sounds more like a honk
I'm swimming
Комментарии:
1. Что касается ошибки echo, я уже объяснил, почему. Это потому, что я бразилец, а на португальском мы говорим «Estou voando!», не используя одинарную кавычку внутри строки, и после вставки я перевел строку на английский. Не беспокойтесь о втором «кряканье!». Я отредактировал содержимое строки, чтобы воспроизвести только одно «кряканье» (для меня это уже слишком кряканье !!!! :). Что касается фактического кода, который вы упомянули, код, который я вставил, является фактическим кодом.
2. Я не смогу вам помочь, если вы не собираетесь читать ответ. Причина, по которой вы видите a,
Quack!<br />
заключается в том, что у вас есть функцияquack()
с тем же именем, что и уQuack
класса, и php автоматически обрабатывает ее как конструктор. Я добавил еще несколько правок, которые могут помочь вам увидеть, как сделать это потенциально лучшим способом…3. Извините… Теперь я понял, что не увидел ответа, который вы дали после горизонтальной линии, и вы абсолютно правы. Большое вам спасибо. Я забыл, что PHP будет обрабатывать любой метод с тем же именем, что и класс, как конструктор класса. Что я сделал, так это переименовал класс Quack в NormalQuack, и весь скрипт работал хорошо. Еще раз большое вам спасибо.
4. Я думаю, что это не лучший способ, потому что он говорит о книге Head First — Шаблоны проектирования, в книге этот пример о том, как не реализовывать quack и летать внутри класса duck, потому что, например, резиновая утка не может летать. Они предлагают создавать интерфейсы и классы и для этого выполнять действия, а затем использовать объекты в конструкторе класса Duck.
Ответ №2:
В вашей ситуации я бы лично предположил, что я что-то упустил из виду, говоря, что echo достигается в коде без вызова этого метода. Я не вижу способа, которым это было бы возможно.
Повторно проанализируйте свой код и поищите хитрый способ, которым ваше echo «Крякнет!выполняется quack!’.
Комментарии:
1. Прежде всего, спасибо за быстрый ответ. Хотя этого может быть недостаточно, но ниже приведено содержимое «функции main()»: $mallard = new Mallard(); $mallard->performFly(); // больше ничего.
2. Во-первых, приведенные выше комментарии просят вас разбить ваш вопрос, а не уменьшать его. Это слишком сложно для чтения. Во-вторых, утки, как известно, крякают, когда рождаются или летают. Я шучу. Но если серьезно, должно быть что-то, вызывающее ваш метод, который содержит инструкцию ‘echo’. он не будет вызывать сам себя. Кое-что должно быть упущено из виду.
3. Я надеюсь, что теперь вопрос стал лучше читаться. Если вы прочитали книгу и протестировали тот же образец, используя Java (я полагаю, вы это сделали), единственное, что вам нужно сделать, это заменить пространство имен Java (например, «System.out.println», void) и объявление на PHP, не более. (Конечно, если у вас есть для этого свободное время).
4. Я не читал книгу. Моим ответом было предложение подойти к вашей проблеме с критическим мышлением. Столкнитесь с проблемой -> предположите ошибку с вашей стороны -> найдите и исправьте ошибку. Я хотел бы помочь вам больше.
5. «Возникла проблема ->» Я пытался!!! «допустим ошибку с вашей стороны ->» Я предполагаю, что со вчерашнего дня я не нашел решения, и это одна из причин, почему я задал этот вопрос. «найдите и исправьте ошибку» если я не исчерпал все возможности, которые пришли мне в голову, опять же, я не задавал этот вопрос и вызвал так много сомнений в умах участников.
Ответ №3:
Прокомментируйте эту строку:
echo 'Quack!<br />';
Вы видите еще какие-нибудь шарлатанства? Если это так, то в вашем коде есть echo / exit / die с этой строкой!
Комментарии:
1. Это всего лишь один шарлатан, ребята!!! Я отредактировал результат echo, чтобы воспроизвести только один. Это потому, что в примере книги авторы, поскольку им очень нравятся утки, написали ‘System.out.println’ с двумя (2) «кряками!». Не имеет значения.
Ответ №4:
Это потому, что когда у вас есть класс с тем же именем метода, PHP рассматривает его как конструктор. Это уже устарело в php 7 и скоро будет прекращено. Вы можете увидеть это в онлайн-документации: http://php.net/manual/en/migration70.deprecated.php