[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Фабрика объектов
Гость_Юрий
Есть класс 'b' - это, так называемая, фабрика объектов (просто фабрика). Бытует мнение, что применение инструкции require_once в классе не желательно - это не правильно. Кто знает более изящное решение для фабрики?

/
/ файл classes.php

class a {

public function get() {

echo 'Гав-гав';

}

}



// файл index.php

class b {

public static function get() {

require_once('classes.php');
return new a();

}

}


b::get()->get();




Спустя 4 минуты, 15 секунд (21.05.2011 - 19:34) Basili4 написал(а):
Гость_Юрий
require_once не применяют из за наличия автолоадера

Спустя 41 секунда (21.05.2011 - 19:35) Greg1978 написал(а):
Использовать "отложенную загрузку".
При первом обращении к файлу файл подключается и фиксируется в массиве его подключение, следующее использование файла не подключит его но вернёт методом true что файл был подключен. Такая "прозрачная" методика.

Спустя 7 минут, 22 секунды (21.05.2011 - 19:42) Basili4 написал(а):
Greg1978
Помоему это излишние действия. Лучше оставить подключения php если класса нет то сработает авто загрузчик если есть то ничего не произойдет.

Спустя 6 минут, 27 секунд (21.05.2011 - 19:48) Гость_Юрий написал(а):
Я так понимаю, что необходимо использовать __autoload()? А примерчик какой-нибудь фабрики с автолойдом можете привести?

Спустя 3 минуты, 2 секунды (21.05.2011 - 19:51) Greg1978 написал(а):
Цитата (Basili4 @ 21.05.2011 - 16:42)
Greg1978
Помоему это излишние действия. Лучше оставить подключения php если класса нет то сработает авто загрузчик если есть то ничего не произойдет.

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

Спустя 3 минуты, 24 секунды (21.05.2011 - 19:55) Basili4 написал(а):
Цитата (Greg1978 @ 21.05.2011 - 20:51)
"виртуального" метода.

хотели сказать магического ? не ?

Спустя 11 минут, 45 секунд (21.05.2011 - 20:07) Гость_Юрий написал(а):
А примерчик какой-нибудь можете привести. Как организовать фабрику по-правильному?

Спустя 6 минут, 32 секунды (21.05.2011 - 20:13) Greg1978 написал(а):
да немного ошибся "мгические"

Спустя 1 минута, 16 секунд (21.05.2011 - 20:14) Guest написал(а):
Ну что, раз молчите, значит голосуем за правильную фабрику (см. ниже). Кто "за"?


// файл classes.php

class a {

public function get() {

echo 'Гав-гав';

}

}


// файл index.php

class b {

public static function get() {

require('classes.php');
return new a();

}

}

b::get()->get();

Спустя 9 минут, 30 секунд (21.05.2011 - 20:24) Greg1978 написал(а):
ни тот не другой
class Factory {

public static function get($className)
{
// По распределению знаний классов отдаём в FileSystem логику проверки
// получаем только ответ

$obj = FileSystem::getFileSystem($className);

if($obj instanceof $className){
return $obj;
}

return false;
}

}

Спустя 10 минут, 52 секунды (21.05.2011 - 20:35) Greg1978 написал(а):
даже так немного неправильно
class Factory {

public static function get($className, $params = false)
{
// По распределению знаний классов отдаём в FileSystem логику проверки
// получаем только ответ

$fileRequire = FileSystem::getFileSystem($className);

if($fileRequire)
{
if($params){
$obj = new $className($params);
}
else {
$obj = new $className();
}

if($obj instanceof $className){
return $obj;
}
else {
throw new Exception('Not instance obj from classes' . $className);
}
}


return false;
}
}

Спустя 1 день, 13 часов, 4 минуты, 7 секунд (23.05.2011 - 09:39) linker написал(а):
Избавляемся от ненужного
$fileRequire = FileSystem::getFileSystem($className);
и добавляем метод
function __autoload($ClassName)
{
$File = './class/' . $ClassName . '.php'; // Тут сам правишь как тебе надо.
if (file_exists($File))
require($File);
else
throw new Exception('Class not found.');
}

Спустя 2 часа, 24 минуты, 22 секунды (23.05.2011 - 12:03) Krevedko написал(а):
крутые начинающие пошли (это я к тому, что тема не в том разделе создана)

Спустя 5 часов, 2 минуты, 8 секунд (23.05.2011 - 17:05) Greg1978 написал(а):
Жажду дальнейшего вразумления smile.gif если понадобиться подключать классы не только из каталога class и не только подключать но и производить свою бизнес логику с ними, точнее жажду обоснованного ответа с учётом распределения знаний по классам.
Спрашиваю это так как фабрика ничего "не должна знать" о работе с файловыми структурами.
В дополнение класс FileSystem может быть локатором, тем самым уменьшаем связь от системы в целом и автолоада который является в данный момент хардкодом, что этим уже оочень не желательно.

Спустя 15 часов, 16 минут, 37 секунд (24.05.2011 - 08:22) linker написал(а):
НУ фабрика и не знает, зато знает __autolaod(), который для того и предназначен чтобы знать где и как располагаются php-скрипты с классами. Причем делается всё автоматом и не надо вручную писать
$fileRequire = FileSystem::getFileSystem($className);
такой ручной метод ничем не отличается от банального, раскиданного по всему коду include()/require().

Спустя 4 дня, 8 часов, 44 минуты, 37 секунд (28.05.2011 - 17:07) Guest написал(а):

<?php

require_once('interfaces/interface.i_NanoBL.php');

abstract class cl_NanoBL_ab implements i_NanoBL {

// Статический массив файловых
// ассоциаций

private static $fileAssociation = array(

/* 1 */ 'vws' => 'views',
/* 2 */ 'cnf' => 'configurations',
/* 3 */ 'reg' => 'registers',
/* 4 */ 'cl' => 'classes',
/* 5 */ 'ctrl' => 'controllers',
/* 6 */ 'com' => 'commands',
/* 7 */ 'ser' => 'services',
/* 8 */ 'mdu' => 'modules',
/* 9 */ 'mdl' => 'models',
/* 10 */ 'fun' => 'functions',
/* 11 */ 'map' => 'mappers'

);

protected $config;

//
public function __construct($config = null) {

$this->config = $config;

}

//
public function setConfig($config) {

$this->config = $config;

}

//
public function getConfig() {

return $this->config;

}

//
public static function searchFile($nameClass) {

$fn = '';

if (!is_string($nameClass)) return $fn;
if (substr_count($nameClass, '/') || substr_count($nameClass, '\\')) return $fn;

$arrDetails = explode('_' , $nameClass);
$pref = $arrDetails[0];

if (isset(self::$fileAssociation[$pref])) $fn .= self::$fileAssociation[$pref] . DIRECTORY_SEPARATOR;

$fn .= 'class.' . $nameClass . '.php';

return $fn;

}

//
public static function factory($nameClass, $config = null, $method = null) {

$fn = self::searchFile($nameClass);
if (!file_exists($fn)) return null;
require_once($fn);
if (!class_exists($nameClass, false)) return null;
if (!$method) return new $nameClass($config);
else return call_user_func_array(array($nameClass, $method), $config);

}

//
public function __destruct() {

$this->config = null;

}

//
public static function system_crash($expr, $message, $nameClass, $numLine) {

if (!$expr) throw new Exception($message . ". Сообщающий класс - '" . $nameClass . "', строка - '" . $numLine . "'");

}

}


?>
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.