Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Классы, методы и параметры
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Классы, методы и параметры

Страниц (2): [1] 2 »
 

1. Slavenin - 16 Июня, 2011 - 21:01:40 - перейти к сообщению
Всем доброго времени суток!

Пришла в голову мысль следующего содержания: "А что если убрать у методов класса все параметры, ввести классу доп поле и необходимые для функции параметры брать из этолго поля?"
пример

PHP:
скопировать код в буфер обмена
  1. class test
  2. {
  3.         var $param;
  4.        
  5.         test()
  6.         {
  7.                 $this->param = array();
  8.         }
  9.        
  10.         function foo()
  11.         {
  12.                 echo $this->param[0];
  13.         }
  14. }
  15. $aaa = new test();
  16. $aaa->param[0] = 'Hellow';
  17. $aaa->foo();


хотелось бы услышать ваше мнение относительно такой конструкции Улыбка
2. DeepVarvar - 16 Июня, 2011 - 21:06:23 - перейти к сообщению
Амёба пра-пра-пра-шаблонизатора Закатив глазки
3. Champion - 16 Июня, 2011 - 21:10:16 - перейти к сообщению
Ну некоторые свойства клссаа могут хранить какие-то его настройки, его состояние, а методы действовать, опираясь на это состояние. Но специально использовать состояние класса как способ передачи параметров - не круто.
Во-первых, непонятно зачем. Во-вторых, можно забыть заполнить какой-нибудь параметр, он будет нести в себе значение с предыдущего вызова, а это весьма неочевидная ошибка, ее долго дебажить придется. Потом, инициализация этих "параметров" метода - лишний код, менее компактный, чем традиционные вызовы. С параметрами по умочанию тоже не очень понятно что делать.
Вот.
4. EuGen - 16 Июня, 2011 - 21:19:41 - перейти к сообщению
Это - side-effect.
side-эффектов надо избегать. Всегда. Не бывает исключений.
Простой пример:
PHP:
скопировать код в буфер обмена
  1.  
  2. class foo
  3. {
  4.    public $param;
  5.    function inverse()
  6.    {
  7.       return 1/$this->param;
  8.    }
  9. }
  10.  
  11. class bar extends foo
  12. {
  13.    public $param;
  14.    function inverse()
  15.    {
  16.       return -1*$this->param;
  17.    }
  18. }
  19.  

А теперь подумаем, как "легко" мы будем следить за состоянием параметров.
5. Slavenin - 16 Июня, 2011 - 21:26:04 - перейти к сообщению
в чем сложность? класс bar наследует и перегружает метод и поле исходного класса соответственно работать мы будем с методами и полями второго класса.
6. EuGen - 16 Июня, 2011 - 21:27:25 - перейти к сообщению
Но мы можем не задать значение параметров дочернего класса.
7. Slavenin - 16 Июня, 2011 - 21:51:38 - перейти к сообщению
именно для этого в каждом классе должен быть конструктор, инициализирующий все ключевые поля.

в общем я понял, что использовать такой способ не есть хорошо.

если есть ссылка про side-effect по-русски буду рад почитать, а то яндекс выдал кучу песен, а гугел ссылки на кучу ненашенских сайтов
8. EuGen - 16 Июня, 2011 - 22:20:00 - перейти к сообщению
side-effect - это "боковой эффект". То есть что-либо, меняющее данные или поведение неявным образом. Яркий пример side-effect - передача параметров по ссылке.
Например, preg_match изменяет третий параметр, помещая туда результат. И это - side-effect.
Использование global (глобальных переменных) есть тоже side-effect (даже в случае, если переменная не меняется), так как изменяет поведение неявно.
Присваивание значений суперглобальным массивам в скрипте можно тоже в большинстве случаев рассматривать как Side-effect.
В общем, идея проста. Функция/метод/класс не имеет side-effect, если его можно взять в цельном виде без контекста и поместить в другой проект, сохранив при этом его работоспособность.
9. Давит - 17 Июня, 2011 - 01:05:03 - перейти к сообщению
Slavenin пишет:
Пришла в голову мысль следующего содержания: "А что если убрать у методов класса все параметры, ввести классу доп поле и необходимые для функции параметры брать из этолго поля?"
пример


Ваш код без var $param; тоже будет работать.
php 5
PHP:
скопировать код в буфер обмена
  1.     class test {
  2.           function  __continue(){
  3.                     $this->param = array();
  4.             }
  5.            
  6.            function  __toString(){
  7.                 return $this->param[0];
  8.             }
  9.     }
  10.     $aaa = new test();
  11.     $aaa->param[0] = 'Hellow';
  12.     echo $aaa;  // вводит "Hellow"


как на вашей примере та и на этой примере не контролируется ситуация, когда создалось что то где то.
Но прежде чем создалось, то что php создал, php в классе питается найти магический метод __set(), но как только php найдет метод __set() в этом случае опять же php будет искать метод __get()
PHP:
скопировать код в буфер обмена
  1.  
  2.     class test {
  3.         public $_test;
  4.         function  __set($n, $v) {
  5.             $this->_test[$n] = $v;
  6.             }
  7.                        
  8.                 function  __get($n) {
  9.              return $this->_test[$n];
  10.             }  
  11.     }
  12.     $aaa = new test();
  13.     $aaa->param = 'Hellow';
  14.     echo $aaa->param;  // вводит "Hellow"


Практически можно взять на контроль

PHP:
скопировать код в буфер обмена
  1.     class test {
  2.         private $_test;
  3.         function  __set($n, $v) {
  4.                         switch ($n){
  5.                                 case "param":
  6.                                    $this->_test=$v; break;
  7.                                  default:
  8.                                    echo "Error!";
  9.                                 }
  10.  
  11.             }
  12.                        
  13.                 function  __get($n) {
  14.            switch ($n){
  15.                                 case "param":
  16.                                   return $this->_test; break;
  17.                                  default:
  18.                                    echo "Error!";
  19.                                 }
  20.             }  
  21.     }
  22.     $aaa = new test();
  23.     $aaa->param = 'Hellow';
  24.     echo $aaa->param."<br>";  // вводит "Hellow"
  25.         echo $aaa->param111."<br>";  // вводит "Error!"
10. Stierus - 17 Июня, 2011 - 11:10:18 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. class test{
  2.         var $param;
  3.         test(){
  4.                 $this->param = array();
  5.         }
  6.  
  7.         function foo(){
  8.                 echo $this->param[0];
  9.         }
  10. }
  11.  
  12. $aaa = new test();
  13. $aaa->foo();

Что выдаст? ... ошибку ... фатальную Улыбка Хотя поведение вполне нормальное и ложится в логику любого программиста.

Как вы дебажить такие классы будете? Откуда вы знаете, что будет лежать в этом param[0] ?

Есть такая штука, как геттеры и сеттеры, вы о них знаете?

Какие проблемы можно решить с помощью вашего класса? Если есть хоть 1 проблема, самым удобным решением которой было бы использовать ваш класс - значит класс юзабельный.
(Добавление)
Любая функция и класс должны описываться неким интерфейсом, как должен выглядеть интерфес для этого класса?
11. Slavenin - 17 Июня, 2011 - 12:12:00 - перейти к сообщению
Цитата:
Есть такая штука, как геттеры и сеттеры, вы о них знаете?

знаю Улыбка
Stierus пишет:
как должен выглядеть интерфес для этого класса?

ну например так
PHP:
скопировать код в буфер обмена
  1. interface ITemplate
  2. {
  3.     public function foo();
  4.  }
  5.  
  6. class test implements ITemplate
  7. {
  8.         var $param;
  9.         test()
  10.         {
  11.                 $this->param = array();
  12.         }
  13.  
  14.         function foo(){
  15.                 (count($this->param) > 0) ? print_r($this->param) : 'Значение не определено';
  16.         }
  17. }
  18.  
  19. $aaa = new test();
  20. $aaa->foo();
12. Stierus - 17 Июня, 2011 - 12:33:07 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. interface ITemplate{
  2.     public function foo();
  3. }

Пример нормального интерфейса:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. /**
  3.  * Все классы, реализующие этот интерфейс, являются хранилищами данных для корзины
  4.  * на текущий момент написано 3 класса, реализующих этот интерфейс :
  5.  * CookieEngine, DbEngine, MemcacheEngine
  6.  */
  7. interface ICartEngine {
  8.  
  9.         /**  
  10.          * функция возвращает массив объектов ICartGood из хранилища
  11.          * @abstract
  12.          * @return array
  13.          * <code>
  14.          *  array(
  15.          *      good_id => ICartGood[],
  16.          *      good_id => ICartGood[]
  17.          *  );
  18.          * </code>
  19.          */
  20.         public function getData();
  21.  
  22.         /**
  23.          * @abstract ф-я добавляет в текущую корзину пользователя товарное предложение
  24.          * @param  int $good_id - id товарного предложения
  25.          * @param int $cnt - количество добавляемого товарного предложения
  26.          *
  27.          * @throws Exception
  28.          *
  29.          * @return bool
  30.          */
  31.         public function add($good_id, $cnt = 1);
  32.  
  33.         /**
  34.          * @abstract Ф-я удаляет товарное предложение из корзины (
  35.          * @param int $good_id - id товарного предложения
  36.          *
  37.          * @throws CartGoodException
  38.          *
  39.          * @return bool
  40.          */
  41.         public function delete($good_id);
  42.  
  43.         /**
  44.          * @abstract ф-я устанавливает количество товарнорго предложения, id которго указан
  45.          * в первом параметре, если такое уже есть в корзине, если нет - выбрасывается исключение
  46.          *
  47.          * Эта ф-я удобна тем, что не нужно знать, увеличивается или уменьшается кол-во товара (например,
  48.          * пользователь руками вбивает новое значение)
  49.          * @param int $good_id - id товарного предложения
  50.          * @param int $cnt - количество товарного предложения
  51.          *
  52.          * @throws CartGoodException
  53.          *
  54.          * @return bool
  55.          */
  56.         public function setQuantity($good_id, $cnt);
  57.  
  58.         /**
  59.          * @abstract Ф-я меняет номер товарного предложения, не меняя количества. Это требуется для
  60.          * изменения метасвойств товара (при этом происходит смена товарного предложения, хотя пользователь
  61.          * этого не замечает, ему кажется, что он сменил цвет нужного товара)
  62.          * @param  $good_id_was id товарного предложения которое нужно изменить
  63.          * @param  $good_id_new id товарного предложения на которое нужно изменить
  64.          *
  65.          * @throws Exception если $good_id_new нет, либо он недоступен в настоящий момент для продажи
  66.          * @throws CartGoodException если $good_id_was в корзине нет
  67.          *
  68.          * @return bool
  69.          */
  70.         public function replaceGood($good_id_was, $good_id_new);
  71. }
13. Slavenin - 17 Июня, 2011 - 14:55:21 - перейти к сообщению
Stierus, все это конечно хорошо. пример нормального интерфейса я и сам могу привести. Улыбка Разговор шел про класс-пример. Хм с тем же успехом имена параметров можно заменить на порядковые номера массива. Закатив глазки
14. Stierus - 17 Июня, 2011 - 15:09:52 - перейти к сообщению
"А что если убрать у методов класса все параметры, ввести классу доп поле и необходимые для функции параметры брать из этолго поля?"


единственный вопрос - "зачем?" ... к ответу на этот вопрос я и пытаюсь вас привести наводящими вопросами.
(Добавление)
Да и пример интерфейса привел для этого же ... интерфейс должен четко описывать, что делает функция, что принимает, какие исключения и когда выкидывает и какой тип данных (если это объект или массив - какая у них структура или тип) возвращает. если вы сможете составить интерфейс, отвечающий на все эти вопросы - значит класс юзабельный и в каких-то случаях даже полезный. Лично я не вижу, как мне ответить на эти вопросы.
15. Slavenin - 17 Июня, 2011 - 15:35:15 - перейти к сообщению
Stierus пишет:
единственный вопрос - "зачем?"

для того чтобы полностью скрыть реализацию функции в классе. Была мысль реализовать этот параметр как приватный и в виде стека и работать с ним только специальными функциями. Ниндзя к тому же нет необходимости в переменных которые будут курсировать по коду, каждая функция знает какой параметр ей нужно использовать, при нормальной реализации она будет выбрасывать исключение если параметр несоответствующего типа или не определен.

эх, жаль все-таки, что php не строго типизированный язык... многих проблем можно было бы избежать...

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

 

Powered by ExBB FM 1.0 RC1