За последние 24 часа нас посетили 9290 программистов и 443 робота. Сейчас ищут 173 программиста ...

Классы, полиморфизм, интерфейсы, финал

Тема в разделе "PHP для профи", создана пользователем askanim, 10 май 2017.

  1. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    аргументируй. Там не сказано получение файлов, там сказано :
    Я написал как они и просили, я описал если они скажут какой тип данных передаётся то он вызовет определённый метод, ток как будет получатся файл это уже десятый вопрос, его можно получить хоть file_get_contents хоть через форму. Я считаю второе задание решено верно, если нет надо чётче давать инструкции если нет полного тз, то выдумывать можно что угодно.
    Ты имеешь ввиду количество дубликатов по полю логин или что хотят они какая цель приследуется? Ну в любом случаю по WHERE login=:login а там уже можно хоть COUNT считать сколько их или чего хотите, не понятно.

    Но это всё мелочи мне просто это как плевок в лицо, что меня отправляют читать курсы про циклы в php
    --- Добавлено ---
    Не понял ты о чём?
    --- Добавлено ---
    Смотря как файл отдавать, если это file_get_content то лучше указать в ручную, если же ты получаешь глобальный массив _FILES то тогда можно и внутри автоматически, но мне кажется по логике вещей это разные классы и они должны быть разделены один получение файлов, а другой это класс работы с файлом. Тебе не кажется что логика здесь должна быть разделена именно так?
     
    #1 askanim, 10 май 2017
    Последнее редактирование: 10 май 2017
  2. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    717
    Тут не надо выдумывать ничего, твоя задача показать своё ООП согласно условиям. К примеру так (очень образно).

    PHP:
    1. class Worker
    2. {
    3.     protected $filePath = '';
    4.  
    5.     public function __construct(string $filePath)
    6.     {
    7.         $this->filePath = $filePath;
    8.     }
    9.  
    10.     public function handle() {
    11.         $adapter = $this->getFileAdapter();
    12.         $adapter->toArray($this->filePath);
    13.     }
    14.  
    15.     protected function getFileExt() {
    16.         return 'ext';
    17.     }
    18.  
    19.     protected function getFileAdapter() {
    20.         $ext = $this->getFileExt();
    21.         if ($ext === 'xlsx') {
    22.             return new XLSXAdapter();
    23.         }
    24.         throw new Exception('File adapter not found!');
    25.     }
    26.  
    27. }
    28.  
    29. interface FileAdapter
    30. {
    31.     public function toArray($filePath) : array ;
    32. };
    33.  
    34. class XLSXAdapter implements FileAdapter
    35. {
    36.  
    37.     public function toArray($filePath) : array
    38.     {
    39.         return [];
    40.     }
    41. };
    --- Добавлено ---
    Там прямо сказано про расширение. Получили путь к файлу - работаем. Всё.
     
  3. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    Стоп стоп, а если файл передаётся путём upload и лежит в массиве $_FILES То твоя конструкция не верна.
     
  4. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.846
    Симпатии:
    1.543
    Да ладно, что там непонятного-то?
    PHP:
    1. public function dataType($typeFile)
    2.     {
    3.         if (empty($typeFile)) {
    4.             return false;
    5.         }
    6.         switch ($typeFile) {
    7.             case 'xml':
    8.                 $this->xml = true;
    9.                 break;
    10.             case 'doc':
    11.                 $this->doc = true;
    12.                 break;
    13.             case 'txt':
    14.                 $this->txt = true;
    15.                 break;
    16.             default:
    17.                 return false;
    18.         }
    19.         return $this;
    20.     }
    Такой код любой чел, знакомый с ООП, тебе забракует. Где полиморфизм?
     
    #4 mkramer, 10 май 2017
    Последнее редактирование: 10 май 2017
  5. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer ладно я успокоился меня просто бесит что я пролетел и я вроде понимаю что такое полиморфизм и пишу сейчас алгоритм тока где то чё то не догоняю, пытаюсь реализовать на интерфейсах но не могу понять как проверить и какой именно нужно метод вызвать для этого.
    --- Добавлено ---
    PHP:
    1. class HandleFile
    2. {
    3.     public function __construct($typeArray)
    4.     {
    5.         foreach ($typeArray as $type) {
    6.             if ($type instanceof \intHandleFile) {
    7.                 $type->HandleType();
    8.             }
    9.         }
    10.     }
    11. }
    12. interface intHandleFile
    13. {
    14.     public function HandleType() ;
    15. }
    16.  
    17. class Xml implements intHandleFile
    18. {
    19.     public $type;
    20.     public $file;
    21.     public function HandleType () {
    22.         if ($this->type === true) {
    23.             echo $this->type;
    24.         }
    25.  
    26.     }
    27. }
    28. class Doc implements intHandleFile
    29. {
    30.     public $type;
    31.     public $file;
    32.     public function HandleType () {
    33.         if ($this->type === true) {
    34.             echo $this->type;
    35.         }
    36.     }
    37. }
    38. class Txt implements intHandleFile
    39. {
    40.     public $type;
    41.     public $file;
    42.     public function HandleType () {
    43.         if ($this->type === true) {
    44.             echo $this->type;
    45.         }
    46.     }
    47. }
    --- Добавлено ---
    Я полагаю вторая задача типа должна решаться как то так?
    --- Добавлено ---
    Чутка переделал, на вот так:
    PHP:
    1. class HandleFile
    2. {
    3.     static public function handle($typeArray)
    4.     {
    5.         foreach ($typeArray as $type) {
    6.             if ($type instanceof \intHandleFile) {
    7.                 $type->HandleType();
    8.             }
    9.         }
    10.     }
    11. }
    12.  
    13. interface intHandleFile
    14. {
    15.     public function HandleType();
    16. }
    17.  
    18. class Xml implements intHandleFile
    19. {
    20.     private $type;
    21.     private $file;
    22.  
    23.     public function __construct($type, $file)
    24.     {
    25.         $this->type = $type;
    26.         $this->file = $file;
    27.     }
    28.  
    29.     public function HandleType()
    30.     {
    31.         if ($this->type === 'xml') {
    32.             echo $this->type;
    33.         }
    34.  
    35.     }
    36. }
    37.  
    38. class Doc implements intHandleFile
    39. {
    40.     private $type;
    41.     private $file;
    42.  
    43.     public function __construct($type, $file)
    44.     {
    45.         $this->type = $type;
    46.         $this->file = $file;
    47.     }
    48.  
    49.     public function HandleType()
    50.     {
    51.         if ($this->type === 'doc') {
    52.             echo $this->type;
    53.         }
    54.     }
    55. }
    56.  
    57. class Txt implements intHandleFile
    58. {
    59.     private $type;
    60.     private $file;
    61.  
    62.     public function __construct($type, $file)
    63.     {
    64.         $this->type = $type;
    65.         $this->file = $file;
    66.     }
    67.  
    68.     public function HandleType()
    69.     {
    70.         if ($this->type === 'txt') {
    71.             echo $this->type;
    72.         }
    73.     }
    74. }
    75.  
    76. $docOne = new Doc('doc', file_get_contents(__DIR__ . '/doc.doc'));
    77. $arr = [
    78.     $docOne
    79. ];
    80. HandleFile::handle($arr);
     
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.846
    Симпатии:
    1.543
    Да не, это скучно. Тебе же @romach приводил решение. Должен быть набор классов для обработки каждого типа файла, и фабрика, которая получает файл, выделяет расширение и на его основе создаёт нужный класс. Тогда это будет расширяемо - при добавлении новых классов меняется только фабрика. А с PHP мы вообще можем сделать, чтоб ничто менять не нужно было, с его способностью брать имя класса из строковой переменной. Я обычно так и делаю.
    PHP:
    1. abstract class FileHandler {
    2.       abstract function handle($file);
    3.       static public function factory($fname) {
    4.           $className = ucfirst(strtolower(path_info($fname, PATHINFO_EXTENSION))) . "Handler";
    5.           if (!class_exist($className)) {
    6.               throw new Exception("Undefined handler");
    7.           }
    8.           return new $className;
    9.       }
    10. }
    11.  
    12. class TxtHandler extends FileHandler{
    13.     function handle($file) { echo "$file - это TXT"; }
    14. }
    15.  
    16. class XlsHandler extends FileHandler{
    17.     function handle($file) { echo "$file - это XLS"; }
    18. }
    19.  
    20. $fname = "/path/f.txt";
    21. FileHandler::factory($fname)->handle($fname);
    Это - паттерн фабричный метод.
    --- Добавлено ---
    У Зандстры много примеров. Правда, там он использует switch, но даже со switch решение неплохо, поскольку он только в одном месте, и при расширении иерархии его нужно будет исправить один раз (и в . А этот вариант вообще не нужно исправлять. Добавляй классов сколько хочешь.
    --- Добавлено ---
    https://www.youtube.com/playlist?list=PLmqFxxywkatStbd9hdzVOS1hZa9dc56k4 - вот этот курс посмотри. Дядька правда джавист, но объясняет шикарно паттерны. Параллельно с Зандстрой хорошо идёт. Я сам не каждый раз применяю паттерны, иногда просто лень :) Но знать надо.
    --- Добавлено ---
    Весь смысл ООП в том, чтобы не проверять, какой метод вызывать. Все паттерны - именно об этом. Иначе классы мало смысла имеют - можно с тем же успехом просто разбить программу на модули, будет тоже структуированно.
     
    askanim нравится это.
  7. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.635
    Симпатии:
    424
    Адрес:
    РД, г. Махачкала.
    Ты слишком много не нужного тянешь от типа к типу, т.е. не используешь ООП как нужно.
    PHP:
    1. <?php
    2.  
    3. abstract class Handler {
    4.  
    5.     abstract function read();
    6.  
    7.     abstract function write();
    8.  
    9.     static function getInstance($extension) {
    10.         switch ($extension) {
    11.             case "txt":
    12.                 return new TxtHandler();
    13.             case "xml":
    14.                 return new XmlHandler();
    15.  
    16.             default :
    17.                 throw new Exception('Handler not found');
    18.         }
    19.     }
    20.  
    21. }
    22.  
    23. class TxtHandler extends Handler {
    24.  
    25.     public function read() {
    26.         echo "txt read()";
    27.     }
    28.  
    29.     public function write() {
    30.         echo "txt write()";
    31.     }
    32.  
    33. }
    34.  
    35. class XmlHandler extends Handler {
    36.  
    37.     public function read() {
    38.         echo "xml read()";
    39.     }
    40.  
    41.     public function write() {
    42.         echo "xml read()";
    43.     }
    44.  
    45. }
    46.  
    47. $obj = Handler::getInstance('xml');
    48. $obj->read();
    49. $obj->write();
    Тут важно позаботиться о инклуде файла класса, иначе опа. В этом случае ведь автолоад не сработает. Конечно я понимаю, что это не конечная реализация, но моя не успокоилась бы пока не написал, не знаю чего я такой придирчивый.

    @askanim, все примеры которые тут приводились, и решение этой тестовой задачи есть в книге "PHP Объекты, шаблоны и методики программирования" Мэтт Зандстра. Советую тебе его почитать.
    --- Добавлено ---
    Ах да, при использовании я забыл заключить в try catch для перехвата исключения.
     
    igordata нравится это.
  8. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.846
    Симпатии:
    1.543
    С какой это радости он не сработает? Работает, проверено. Естественно, в реальных проектах я ещё правильное пространство имён подставляю Т.е. было бы
    PHP:
    1. $className = __NAMESPACE__ . '\Handlers\\' . ucfirst(strtolower(path_info($fname, PATHINFO_EXTENSION)))."Handler";
    Автолоад для динамически сформированного имени тоже работает - а что, в фреймворках тоже switch() стоит, чтоб мои контроллеры грузить? Откуда они их имена знают? Особенно те, что роуты а-ля /controller/action вообще без моего участия разрешают в имя класса и функцию, к примеру Yii2.
     
    #8 mkramer, 11 май 2017
    Последнее редактирование: 11 май 2017
    mahmuzar нравится это.
  9. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mahmuzar, @mkramer Не ну вы серьёзно? Вы думаете я не знаю что аткое полиморфизм и какими средствами в php можно его организовать, да сделать можно как угодно, я даже помню я создавал тему про интерфейсы где я предлогал собирать модели по инструкции однотипной. А именно вот здесь:
    https://php.ru/forum/threads/interfejsy.63084/ .
    Ещё раз только киньте в меня книгой зандстры, я её видел. Я полиморфизм на абстрактных классах прошёл ещё полтара года б*я тому назад. Просто я его на столько крайне редко юзаю что просто про него забыл. Но чтобы его заюзать должна быть прямо необходимость.
    --- Добавлено ---
    Можно я кого нибудь покусаю... :D
     
  10. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    Спасибо. Я уже это услышал в первом твоём посте что там полиморфизм. И я тогда тут же начал писать код и потом прикрепил на что ты мне показал паттерн фабричный метод, мне понравилось, я решил только сделать его на интерфейсах а не на абстрактных чуть позже выложу времени мало надо в офис бежать. А потом вы ещё 10 раз обсмоковали и кинули книгой в меня, я ведь правильно показал полиморфизм когда прикрепил код? Скучно может быть но полиморфизм я привёл верно?
    да я не понятно зачем написал библиотеку. Хз как так вышло :D
    --- Добавлено ---
    этого я не знал паттерна.
    --- Добавлено ---
    Не хватка практического опыта :( К сожалению весь мой опыт это работа над собственными проектами либо же опыт работы на сообственных клиентов. Я бы хотел пойти в большую компанию для получения такого опыта. Но к сожалению пока не могу найти место. :(
     
  11. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.846
    Симпатии:
    1.543
    Ну так, кинули книгой - потому что там ещё много интересного, помимо фабричного метода. Как и в лекциях джависта, которые кинул я :) Паттерны показывают как раз наиболее эффективное использование полиморфизма, а не просто что это такое. Я сам долго писал без них, пока в одном проекте не утонул в собственном говнокоде. Порождающие паттерны (синглтон, фабрика/фабричный метод, абстрактная фабрика) - это то, о чём надо всегда помнить. Да, есть несколько реализаций. Мне нравится фабричный метод в абстрактном родителе, можно вынести его в отдельный класс. Но, главное, чтоб клиенту, обращающемуся к фабрике, не приходилось самому заботится о том, какой класс почему надо создать. Сосредоточить логику выбора в одном месте. И вообще, не надо любую ссылку на учебный материал принимать за оскорбление :) В нашей профессии всё так быстро устаревает/меняется, что что-то читать нужно постоянно.
     
    askanim нравится это.
  12. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    Это я в избранное добавил.
    Мне показал Игорёк ^^ Я вот сейчас пишу на нём библиотеки для работы с базой в нашем проекте :)
    --- Добавлено ---
    это точно
     
  13. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.635
    Симпатии:
    424
    Адрес:
    РД, г. Махачкала.
    Когда то с этим у меня были проблемы, сейчас проверил, работает как надо. Вероятно, на тот момент я что-то делал не так).
     
  14. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer У меня оказывается есть купленный экземпляр книги зандстры :D Сегодня засел читать. Честно скажу чувак крут. Начал с 9 главы генерация объектов, мне даже в голову кое что не приходило что так можно делать :)
    --- Добавлено ---
    @human1 да книга крутая :) Она реально хороша) Я вот сижу читаю шаблоны проектирования и понимаю как круто можно на самом деле писать код)
     
  15. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.165
    Симпатии:
    1.762
    Адрес:
    :сердА
    Фабрика - чуть ли не самый широко известный. Она с синглетоном, наверное, на первых местах по популярности и наслышанности. Хотя, справедливости ради, то, что тут озвучивали, на самом деле не столько "фабрика", сколько "стратегия".
     
  16. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    Я сегодня изучал зандстру, 9 главу всю изучил Очень инетресно. И теперь я не просто слышал об этих названиях, теперь ещё я знаю что это и как это, и в принципе не совсем конечно пока до конца - куда это)
     
  17. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.846
    Симпатии:
    1.543
    Они все переплетены, но всё же функции создают объекты, выбирая подходящий. И никуда его не передают. А вообще, тут может быть всё вместе. Типа, какой-нибудь TableImporter получает либо CSVTableFile или XLSTableFile, которые соответственно реализуют либо построчное чтение CSV, либо построчное чтение Ёклселя. А два последних могут создаваться методом factory() абстрактного класса TableFile. Всё-таки пораждающие шаблоны всегда рассматриваются первыми, поскольку все эти стратегии и т.д. тоже надо где-то создавать :)
     
  18. askanim

    askanim Активный пользователь

    С нами с:
    7 апр 2016
    Сообщения:
    2.192
    Симпатии:
    166
    Адрес:
    GABRIEL
    @mkramer а мне всё таки больше нравится использование интерфейсов чем абстрактных классов, ведь в принципе через них можно реализовать тоже что и делает зандстра с абстрактными) Ну правда будет ещё входящий класс)
     
  19. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.846
    Симпатии:
    1.543
    Они взаимозаменяемые. В интерфейс не засунуть поведение, в абстрактный класс - засунуть. Хотя я иногда создаю интерфейс => абстрактный класс => Конкретная реализация. Всё зависит от задачи. Иногда я вообще пишу if, думаю, а хорошо бы тут стратегию. Потом думаю - здесь пока и иф неплохо смотрится, и оставляю так. Всё зависит от задачи. Чем сложнее задача, тем больше от этого всего пользы
     
    askanim нравится это.
  20. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.165
    Симпатии:
    1.762
    Адрес:
    :сердА
    Но только в не абстрактный метод.

    Интерфейс это, по-сути более строгая структура относительно абстрактного класса. И более молодая хронологически. Она не лучше абстракта и не хуже. Если понимаешь, что делаешь, не особо принципиально, что именно используешь. Разве что интерфейсы, местами, чисто вот семантически больше к месту приходятся.

    Это еще в пхп опущена тема виртуальных классов, в силу того, что тут все классы - априори виртуальные. Мб это и правильно, конечно, но меня немного коробит от невозможности управления оверрайдингом в потомках. А потом я оборачиваюсь на JavaScript и понимаю, что все не так и плохо.
     
  21. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.846
    Симпатии:
    1.543
    А final?
     
  22. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.165
    Симпатии:
    1.762
    Адрес:
    :сердА
    Оу, точно. Прошляпил этот момент. Получается, вообще зеркальное отражение "классической парадигмы" виртуальных методов :)
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.419
    Симпатии:
    1.742