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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Приватные методы __construct () и __clone ()

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
Zingeon
Отправлено: 10 Ноября, 2013 - 14:07:06
Post Id



Новичок


Покинул форум
Сообщений всего: 15
Дата рег-ции: Авг. 2013  


Помог: 0 раз(а)




Я только начал постигать основы ООП, но у меня возник сильно волнующий меня вопрос, так что заранее извиняюсь за написанные глупости. Вот мы, когда объявляем методы __construct () и __clone () приватными, то вне класса делаем невозможным вызов этих функций. Это понятно и логично. Но я никак не могу понять, почему не можно будет применить к классу оператор new? Почему в этом случае нельзя создать объект класса, и просто вызвать из него какой-то метод или свойство? Ведь __construct () и __clone () призваны быть как бы вспомогательными методами в классе, но вовсе не обязательными, т.е. без них можно в ряде случаев просто обойтись, и когда мы объявляем их приватными, то каким боком это затрагивает невозможность создания нового экземпляра класса? Надеюсь, понятно сформулировал свою мысль
 
 Top
OrmaJever Модератор
Отправлено: 10 Ноября, 2013 - 14:16:12
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Если конструктора нет то нет, а если есть то его нужно вызвать, ну а поскольку он приватный то и появляется сообщение о вызове приватного метода.
Мне интересно зачем вам приватный конструктор?


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
Zingeon
Отправлено: 10 Ноября, 2013 - 14:44:58
Post Id



Новичок


Покинул форум
Сообщений всего: 15
Дата рег-ции: Авг. 2013  


Помог: 0 раз(а)




OrmaJever пишет:
Мне интересно зачем вам приватный конструктор?


Я пытаюсь разобрать принцип действия шаблона singleton, и там как раз это является основой данного паттерна
 
 Top
teddy
Отправлено: 10 Ноября, 2013 - 14:52:12
Post Id


Участник


Покинул форум
Сообщений всего: 1462
Дата рег-ции: Апр. 2013  


Помог: 91 раз(а)




PHP:
скопировать код в буфер обмена
  1. class A{
  2.     static private $_instance = null;
  3.     static function getInstance(){
  4.       if(self::$_instance === null){
  5.          self::$_instance = new self();
  6.             return self::$_instance;
  7.           }
  8.        }
  9.      private function __construct(){}
  10.      private function __clone(){}
  11.        
  12.      function sayHello(){
  13.          echo 'Hello, world!';
  14.      }
  15.        
  16. }
  17. $obj = A::getInstance();
  18. $obj->sayHello();

Вот пример синглтона. Это легко. Как видите, создается статичный метод, который чекает флаг(статичное свойство класса $_instance), если оно null, тогда класс записывает в него самого себя(создает объект) и это можно использовать. сделайте var_dump($obj) и обратите внимание, что метод sayHello был успешно вызван... Думаю всё ;)
 
 Top
Zingeon
Отправлено: 10 Ноября, 2013 - 15:05:45
Post Id



Новичок


Покинул форум
Сообщений всего: 15
Дата рег-ции: Авг. 2013  


Помог: 0 раз(а)




OrmaJever и teddy, спасибо за объяснения! В довершение этому, я поэкспериментировал с примером кода singleton, и наконец-таки разобрался что к чему!
 
 Top
OrmaJever Модератор
Отправлено: 10 Ноября, 2013 - 15:29:37
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




Zingeon если вы не хотите что бы кто-то создал объект через new (а не статическую функцию) то напишите в конструкторе
PHP:
скопировать код в буфер обмена
  1. die('Use A::getInstance() to get object');

и всё будет нормально.


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
EuGen Администратор
Отправлено: 10 Ноября, 2013 - 16:51:00
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




OrmaJever
В корне плохая идея. exit не предоставляет никакой возможности или свободы при выборе действий. Таким образом, прерывая исполнение скрипта, исключается любая возможность определить реакцию на возникшую ситуацию. Корректный способ - использовать исключения (Exception), но даже и так - в ряде случаев приватный конструктор может принимать параметры и использоваться в других статических методах, инстанцирующих объект.

Насчёт синглтона - его польза в PHP стремится к нулю, по сути это почти всегда антипаттерн. Разумное правило - если объект не должен существовать более, чем в одном экземпляре - не инстанцировать его более одного раза. Хорошее пояснение почему это так для PHP есть здесь

Насчёт статических методов - их лучше избегать. Есть немного случаев, когда их использование оправдано (например, уже упомянутые выше инстанцирующие методы, которые по определению не могут быть иначе как статичными ввиду отсутствия контекста объекта при их вызове). Общее пояснение - статические методы трудно тестировать, они являются, по сути, неявным побочным эффектом (side-effect), так как переносят общий контекст между разными объектами - а это затрудняет читаемость, переносимость и поддержку кода в большинстве случаев.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
DelphinPRO
Отправлено: 10 Ноября, 2013 - 17:35:52
Post Id



Активный участник


Покинул форум
Сообщений всего: 7187
Дата рег-ции: Февр. 2012  


Помог: 353 раз(а)




EuGen пишет:
В корне плохая идея. exit не предоставляет никакой возможности или свободы при выборе действий.

В данном случае никакой свободы и не должно быть. Программист еще на этапе разработки поймает эту ошибку, и перепишет код правильно. А уж в готовом продукте такой тип ошибки возникнуть не может.


-----
Чем больше узнаю, тем больше я не знаю.
 
 Top
EuGen Администратор
Отправлено: 10 Ноября, 2013 - 17:49:02
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




DelphinPRO
Нет, вероятно, посыл не был понят. Если это случай, когда класс разрабатывается для самого себя - то вполне достаточно сделать конструктор приватным (для самого себя нет нужды использовать exit - ведь про свои действия каждый в курсе).

Но вот если предполагается использовать класс как часть некоторого API - или части библиотеки - словом, если пользователями будут сторонние разработчики, которые могут использовать его в динамическом контексте - exit выглядит плохим решением.

Разумеется, я имею ввиду связку обычного (публичного) конструктора + exit, так как в случае с приватным конструктором возникнет Fatal error ещё до вызова exit


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Ch_chov
Отправлено: 10 Ноября, 2013 - 17:52:21
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




А разве приватный конструктор не приводит к Fatal Error при попытке создать объект стандартным способом?
 
 Top
EuGen Администратор
Отправлено: 10 Ноября, 2013 - 17:54:40
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Ch_chov пишет:
А разве приватный конструктор не приводит к Fatal Error при попытке создать объект стандартным способом?

Приводит. О том и речь. А раз так, я предполагаю, что предложенный вариант с exit относится к публичному конструктору - и потому считаю это плохой идеей (и, если уж есть такая необходимость, корректнее использовать исключения, хотя и с ними такой подход выглядит в лучшем случае странным).


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Ch_chov
Отправлено: 10 Ноября, 2013 - 18:13:45
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




Исключения удобны тем, что их можно обработать. Даже если это действительно фатальная ошибка приложения, поможет корректно её обработать. Записать ошибку в журнал, отправить уведомление админу и т.д. В некоторых случаях его даже и перехватывать не надо. Если php установлен как модуль Apache, то все не обработанные исключения (в том числе собственные) попадаю в error.log.

(Отредактировано автором: 10 Ноября, 2013 - 18:16:19)

 
 Top
DelphinPRO
Отправлено: 10 Ноября, 2013 - 19:46:22
Post Id



Активный участник


Покинул форум
Сообщений всего: 7187
Дата рег-ции: Февр. 2012  


Помог: 353 раз(а)




EuGen пишет:
Нет, вероятно, посыл не был понят.

ясно. забыл что fatal error вылетит раньше exit


-----
Чем больше узнаю, тем больше я не знаю.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB