Master-X
Форум | Новости | Статьи
Главная » Форум » Программинг, Скрипты, Софт, Сервисы » 
Тема: ООП теория
цитата
04/04/15 в 13:09
 Vyacheslav
Вопрос теоретического характера для тех, кто умеет практически реализовывать принципы ООП. (Наглядно плохие примеры, а сам вопрос в конце текста.)

В процедурном программировании мы разбиваем программ на подобные структуры:
Код:

function convertStringToValidFilename($str) {
  ... code ...
  return $newStr;
}


1. Оказывается со временем, что мы хотим пробелы в исходной строке заменять на некий символ, коорый зависит от неких внешних факторов\данных. Переписываем в подключаемом модуле нашу функцию и рефакторим остальной проект!
Код:

function convertStringToValidFilename($str, $separator='_') {
  ... code ...
  return $newStr;
}


2. Тут мы столкнулись с ситуапцией, что для разных ОС есть разные ограничение на длину имени файла (для простоты игнорируем другие ограничения).
Мы можем повесить на пользователя эту задачу и как в п.1., навесив на нашу функцию ещё один параметр $outFilenameMaxLength и отрефакторив код, добавить подобный костыль.
Естественно, лучше пойти другим путём, добавив проверку на разные ОС. Код проверки типа ОС надо вынести в отдельную подпрограмму и как то потом передать результат без глобальных переменных в наш метод\функцию. Тем самым мы сразу задабриваем, как минимум, 2 парадигмы\подпарадигмы ООП:
- каждый метод делает что-то своё и только;
- даём шанс подпрограмме проверки ОС, на повторное использование, вынося его за пределы нашего метода.

Проблемы процедурных языков программирования на лицо, надо переписывать всё заново при расширении. Как подобное решается при корреткном ООП подходе? Я не имею ввиду ликбез по работе с IDE(search\replace) и решении задачи именно при наличии подобной функции как в посте, вопрос скорее в подходе, который не позволит вылезти подобным проблемам. ЯП в ответе не имеет значения.
цитата
04/04/15 в 15:48
 Stek
Vyacheslav писал:
Проблемы процедурных языков программирования на лицо, надо переписывать всё заново при расширении. Как подобное решается при корреткном ООП подходе?

Точно так же smail101.gif Пример со строками вообще не подходит для ООП.
Инициализировать ОС ты можешь в классе, в функции, при запуске скрипта, в конфиге.

Ты можешь иметь класс String , который имеет все нужные тебе функции. Но этот класс в зависимости от ОС наследует StringWin или StringUnix классы, где и происходит обработка строк.

Т.е. в теории работая со String ты не заморачиваешься с ОС. А при необходимости изменяешь и добавляешь другие классы, хоть StringDOS .
цитата
04/04/15 в 18:30
 rx
ммм...

правильный ответ в данном вопросе - уволить прогера который вместо введения стартовой проверки ОС и переопределения глобальной переменной "сепаратор" в случае если ОС отличается от дефалтной, доступной/используемой в ф-ции конверсии, что делается в 2 строки в двух местах без потребности менять что-то еще, начинает вводить новые переменные для ф-ции и рефакторить весь код, сопровождая все это писульками про парадигмы и прочие космические корабли бороздящие просторы вселенной trollface.png
цитата
04/04/15 в 18:32
 Vyacheslav
Увольнять некого. Я пытаюсь для себя понять как именно данный случай надо реализовывать в ООП парадигмах, чтобы можно было без переписывания и рефакторинга расширять код.
Вместо функции создать класс с сетером строки и гетером в виде результата работы? В случае добавления нового параметра будет удобно добавить ещё один сетер для разделителя?
цитата
04/04/15 в 19:23
 rickdeckard
в правильном ООП делается так:

создается ненужный класс

class StringValidFilenameConverter {

// тут ненужный конструктор
public function __construnct($str) {
... чтото инициализируем устанавливаем начальные параметры
}

тут тысячи ненужных гет-сет методов ...

тут метод который делает работу
public convert() {
код метода состоит из вызова мелких методов реализующих проверки и прочее
это надо чтобы пользователь мог породить тысячи классов-гермофродитов переопределя только эти мелкие методы делающие например проверки типа ос и т.п.

веть для чего же ооп еще придумано?
}


}
цитата
04/04/15 в 19:27
 rickdeckard
как делается по нормальному

function convertStringToValidFilename($str) {
тут мы проверяем все условия в зависмости от ОС и не ебем мозг.

устанавливаем нужные $separator='_'
длинну строки и прочее.

return $newStr;
}

в результате мы получаем функцию, которая по строке возвращает валидное имя. и посрать тому кто использует функцию на какие то ограничения.
при этом в дальнейшем не нужно ничего менять по всему коду и рефаткорить его. нужно только поменять тело функции. это невероятно не правда ли?
цитата
04/04/15 в 19:48
 Mika
Vyacheslav писал:
Я пытаюсь для себя понять как именно данный случай надо реализовывать в ООП парадигмах, чтобы можно было без переписывания и рефакторинга расширять код.

Все равно как не сделаешь, а в последствии рефакторить придется, если речь не о проекте сделал-забыл.

rickdeckard писал:
в правильном ООП делается так:

создается ненужный класс

class StringValidFilenameConverter {

Хера себе у вас "правильное ООП" icon_rolleyes.gif
цитата
04/04/15 в 20:19
 Vyacheslav
rickdeckard писал:
как делается по нормальному
...
при этом в дальнейшем не нужно ничего менять по всему коду и рефаткорить его. нужно только поменять тело функции. это невероятно не правда ли?


В теле функции можно поменять, только то, что не учавствует в диалоге с пользователем, как например тип ОС с её ограничениями вданном примере. Херовый деплой, но представим, что пишем для себя и это как-то возможно. А если данный параметр учавствует в диалоге с пользователем посредством интерфейса? Тогда надо передавать его как параметр функции 100% (не юзать же глобал) и рефакторить все точки применения функции в проекте, если надо добавить подобный новый параметр или удалить уже не нужный. Так же подобное число параметров может вырости до эпического числа. В джаваскрипте это решаетеся обьектом скаляром, у которого свойства идут как параметры (я хз как в то м же пхп это решить). Но это ещё один довод не юзать для подобных целей голую функцию в таких языках.
цитата
04/04/15 в 21:19
 Ailk
знач так.
создаешь статик класс, например Tools со своим методом.
Код:
Tools::convertStringToValidFilename($str);

патом значит создаешь второй класс, уже синглтон и где-то там в коде задаешь нужный сепоратор trollface.png
Код:
Config::getInstance()->fileWordSeparator = '_';


потом делаешь так:
Код:

class Tools
{
     public static function convertStringToValidFilename($str)
     {
        return str_ireplace (" " ,Config::getInstance()->fileWordSeparator, $str);
     }
}

PROFIT!!11 smail101.gif trollface.png
цитата
04/04/15 в 22:50
 Stek
Код:

define('SEPARATOR', '_'); // это где то в конфигах
$str = str_ireplace(' ',SEPARATOR ,$str);


ООП имхо предназначено для другого, чем извращать простой код. У пхп программеров ООП вообще приняло жуткую стадию извращенности.
цитата
05/04/15 в 00:31
 Ailk
та хз, курить маны. Есть ведь и такие штуки func_get_args ( void )
решает вроде как проблему 1 поста без рефакторинга всего кода
цитата
09/04/15 в 17:26
 rickdeckard
Vyacheslav писал:
В теле функции можно поменять, только то, что не учавствует в диалоге с пользователем, как например тип ОС с её ограничениями вданном примере. Херовый деплой, но представим, что пишем для себя и это как-то возможно. А если данный параметр учавствует в диалоге с пользователем посредством интерфейса? Тогда надо передавать его как параметр функции 100% (не юзать же глобал) и рефакторить все точки применения функции в проекте, если надо добавить подобный новый параметр или удалить уже не нужный. Так же подобное число параметров может вырости до эпического числа. В джаваскрипте это решаетеся обьектом скаляром, у которого свойства идут как параметры (я хз как в то м же пхп это решить). Но это ещё один довод не юзать для подобных целей голую функцию в таких языках.


теоретизировать можно много чего. если бы да кабы.
можно просто взять и заюзать $GLOBALS тогда. или использовать функцию для представления параметра - если он динамический.

можно обмазыватся рефакторингом а можно писать код делающий полезную работу.

если число параметров возрастает до эпического числа - значит вы делаете чтото не так.
декомпозиция функционала прекрасно реализуется на обычных функциях.

вконтакте написали же на KPHP, без применения ООП.
цитата
09/04/15 в 17:37
 rickdeckard
Ailk писал:
та хз, курить маны. Есть ведь и такие штуки func_get_args ( void )
решает вроде как проблему 1 поста без рефакторинга всего кода


представляю какой трудноотлаживаемый пиздец получится. еще хуже чем с явной передачей всех параметров.
цитата
09/04/15 в 17:42
 rickdeckard
Ailk писал:
знач так.
создаешь статик класс, например Tools со своим методом.
Код:
Tools::convertStringToValidFilename($str);

патом значит создаешь второй класс, уже синглтон и где-то там в коде задаешь нужный сепоратор trollface.png
Код:
Config::getInstance()->fileWordSeparator = '_';


потом делаешь так:
Код:

class Tools
{
     public static function convertStringToValidFilename($str)
     {
        return str_ireplace (" " ,Config::getInstance()->fileWordSeparator, $str);
     }
}

PROFIT!!11 smail101.gif trollface.png

веть namespace уже давно как сделали
а до сих используют классы для неймспейсов
Tools::
Config::

потом инстанс для конфига - нафига?

когда можно просто
$GLOBALS['config']['file_word_separator']
цитата
09/04/15 в 18:33
 Ailk
это было что-то типа сарказма icon_lol.gif

rickdeckard писал:
представляю какой трудноотлаживаемый пиздец получится. еще хуже чем с явной передачей всех параметров.

это ваще не в тему, я поздно ночью писал, толком не прочитал о чем автор пишет. Ну и хуйню сморозил. Там речь вообще шла о местах вызова функции.
цитата
09/04/15 в 20:09
 Stek
rickdeckard писал:
потом инстанс для конфига - нафига?

когда можно просто
$GLOBALS['config']['file_word_separator']


А потом где то в скрипте кто то так же установил переменную, и ты два дня ищешь, откуда бля она вдруг берется и где еще используется smail101.gif
цитата
09/04/15 в 20:22
 Vyacheslav
Вобщем, для себя понял, что пока решением есть перегружать один и тот же метод с разным кол-вом параметров.
Либо через сеттеры инициализировать предварительно обьект и юзать безпараметровый метод, как ту самую функцию-подпрограмму.
rickdeckard писал:
вконтакте написали же на KPHP, без применения ООП.

Если есть достоверная информация, что писали вовсе без ООП, то ладно, но сам kPHP ограничено поддерживает применение ООП. Я не разбирался, но что-то мне подсказывает, что поддерживается именно то, о чём я и говорю в этом топике. Опять же в ПХП есть зачатки функционального программирования. Я это всё к тому, что чисто процедурным далеко не то что вконтакту, даже моим тестовым проектам не уйти. Реально грабли уже на первой полусотне строк начинаются.
цитата
09/04/15 в 20:36
 Stek
Vyacheslav писал:
Реально грабли уже на первой полусотне строк начинаются.

Не надо мудрить там, где оно этого не требует. Как к примеру в данном случае с сепаратором. Это всего лишь одна элементарная функция, на кой черт ее в ООП заворачивать.
цитата
09/04/15 в 20:53
 rx
Vyacheslav писал:
Вобщем, для себя понял, что пока решением есть перегружать один и тот же метод с разным кол-вом параметров.
Либо через сеттеры инициализировать предварительно обьект и юзать безпараметровый метод, как ту самую функцию-подпрограмму.

Если есть достоверная информация, что писали вовсе без ООП, то ладно, но сам kPHP ограничено поддерживает применение ООП. Я не разбирался, но что-то мне подсказывает, что поддерживается именно то, о чём я и говорю в этом топике. Опять же в ПХП есть зачатки функционального программирования. Я это всё к тому, что чисто процедурным далеко не то что вконтакту, даже моим тестовым проектам не уйти. Реально грабли уже на первой полусотне строк начинаются.


Добрый совет - не надо играть в кодинг, наймите нормального программиста, дешевле выйдет trollface.png
цитата
09/04/15 в 20:59
 Vyacheslav
Stek писал:
Не надо мудрить там, где оно этого не требует. Как к примеру в данном случае с сепаратором. Это всего лишь одна элементарная функция, на кой черт ее в ООП заворачивать.

Привёл самый, что не не есть простой пример, но который очень уж часто встречается в том же пхп. Таких функцияй в коде при современном подходе программирования, где повторяющийся код заворачивается в подпрограмму, может появляться до полусотни. Скрипт приходится постоянно дорабатывать. Как правило это связано с админкой, в которой 20-30 страниц и на каждой странице по одной или несколько форм (интерфейсы управления и взаимодействия с пользователем). Для каждой формы своя подпрограмма обработки данных с формы, обойтись без параметров тут не реально. Хоть и каждой форме свой файл скрипта, но обработка не сводится к одному линейному коду. Формы, соответсвенно параметры соответствующие полям формы, постоянно мутируют во время доработок. Сюда же идут ещё параметры из констант конфигов. У функций растёт кол-во параметров, что уже само по себе не комильфо, но, что страшнее, это тянет за собой ещё рефакторинг при любом чихе в точках применения функций. И это только та сторона где идёт работа с GUI. Я в шоке, что там за каша пойдёт дальше.
А сепаратор - это только мелкий пример. Туда уже куча новых параметров добавлено, так как помимо сепаратора, пользователь должен выбрать пропускаемую длинну слова, регистр символов, использовать белый список слов и т.п.
цитата
09/04/15 в 21:56
 Stek
Vyacheslav писал:
Привёл самый, что не не есть простой пример, но который очень уж часто встречается в том же пхп.

На этот пример натянуть ООП можно, но не нужно, не тот уровень.

Vyacheslav писал:
Туда уже куча новых параметров добавлено, так как помимо сепаратора, пользователь должен выбрать пропускаемую длинну слова, регистр символов, использовать белый список слов и т.п.


Код:

<?php
class Parser {
    public static $separator = '_';
    public static $wrap_length = 20;
    public static $wrap_by = '<br />';
   
    private static function correction($string) {
        // что то химичим со строкой
        return $string;
    }
   
    public static function wrap($string) {
        $string = self::correction($string);
        return wordwrap(str_replace(' ', self::$separator, $string), self::$wrap_by, self::$wrap_length);
   }
}

Parser::$wrap_length = 5;
Parser::wrap('Моя длинная строка тут');


Как пример для простой обработки. Можешь хоть юзера так передать, а в приватной функции проверить, что если юзер задан, то вытащить из профайла его настройки и обработать предварительно строку по его правилам.
В любом случае от рефакторинга не уйти.
цитата
09/04/15 в 22:07
 Ailk
дык заранее прикинуть какие нужны будут параметры на этапе проектирования несудьба?
А вообще в функцию можно массив передавать. Оп! И убиваешь сразу двух зайцев. Ненадо рефакторить постоянно, просто где нужно добавляешь
Код:

$data["os"] = get_os();
$data["filename"] = "abc qwerty.jpg";
$filename = convertStringToValidFilename($data);

function convertStringToValidFilename($data)
{
    if ($data["os"] === "windows")
        $separator = "_";
    return str_ireplace (" " ,$separator, $data["filename"]);
}

Или я опять чета не догоняю? ;D
цитата
09/04/15 в 22:27
 Stek
Ailk писал:
А вообще в функцию можно массив передавать. Оп! И убиваешь сразу двух зайцев. Ненадо рефакторить постоянно, просто где нужно добавляешь


Так нельзя делать. Т.е. если у тебя скрипт в 100 строк, то можно. Но если больше - ты просто не сможешь удержать в голове структуру массива. А IDE тебе не сможет подсказать что и как. Времени будет на такой код тратиться дохерища, отлов ошибок затруднен.

Вон ты даже в примере ошибок наделал. А если $data['os'] равно чему то другому ? При подавлении ошибок ты получишь совершенно не предсказуемый результат.
цитата
09/04/15 в 22:38
 Ailk
в целом согласен, и сам не люблю передавать массивы в функцию. Однако много видел писанины с подобной практикой.
а пример упрощен, не стоит цепляться ) можно ведь и через свитч/кейс конструкцию сделать, где по дефолту будет определенный сепор... но это все лирика icon_smile.gif
цитата
13/04/15 в 23:49
 st01en
Stek писал:
Так нельзя делать. Т.е. если у тебя скрипт в 100 строк, то можно. Но если больше - ты просто не сможешь удержать в голове структуру массива. А IDE тебе не сможет подсказать что и как. Времени будет на такой код тратиться дохерища, отлов ошибок затруднен.

Вон ты даже в примере ошибок наделал. А если $data['os'] равно чему то другому ? При подавлении ошибок ты получишь совершенно не предсказуемый результат.


Бедные питонисты с их func(*arg, **kwarg), да?
Стр. 1, 2  >  последняя »


Эта страница в полной версии