<?php
abstract class Entity extends BaseClass {
function __set($Name, $Value)
{
if (method_exists($this, 'set_'.$Name)) {
return call_user_func(array(&$this, 'set_'.$Name), $Value);
}
else {
return parent::__set($Name, $Value);
}
}
function __get($Name)
{
if (method_exists($this, 'get_'.$Name)) {
return call_user_func(array(&$this, 'get_'.$Name));
}
else {
return parent::__get($Name);
}
}
}
Организация структуры в классе. PHP5
Проблемы как таковой нету. Просто есть некоторые вещи, которые хочется понять или узнать возможно ли это.
Вопрос в следующим. пишу щас системку. Вся будет построенна на ООП. Основа точнее. Функционал будет большой, по первым прикидкам. Первое, что хотелось бы - это конечно разбить класс на подгруппы.. Т.е. одна часть отвечает за построение меню, вторая за контент, третья за целостность данных и т.д. Разбить все это на различные файлы нельзя (т.е. разбить класс. Методы раскидать по файлам, а потом объядинять).
Хотелось бы видеть такое. Пример:
Допустим класс имеет некий функционал. А именно:
1) за проверку целостности данных отвечает MD5Files
2) за вывод меню отвечает Menu
3) за шаблон, вывод инфы отвечает TPL
Код:
class Main {
private function some() {
$this->MD5Files->check();
$this->Menu->Build();
$this->TPL->print();
}
}
private function some() {
$this->MD5Files->check();
$this->Menu->Build();
$this->TPL->print();
}
}
но есть одно НО. Я не знаю как присвоить вот этим MD5Files, Menu и т.д. методы.. Т.е. я могу в классе Main создать объект, у которого будут свойтсва, но никак не методы..
Также есть варианты:
1) использовать наследование (extends) - но невозможно на PHP создать класс с несколькими предками.
2) есть вариант каждому классу (MD5Files, TPL,...) становится потомком.. Но это совсем не то.. Так как тот же Menu должен взаимодействовать с Main, TPL и MD5Files.. Все взаимосвязано
3) наследовать неявно... т.е. добавить что-то типа этого:
Код:
class Main {
// $Module - создается вне класса, хотя можно создавать и в классе Main - без разницы
public function loadModule($className,&$Module) {
switch($className) {
case "MD5Files":
$this->MD5Files=$Module;
break;
}
}
private function some() {
$this->MD5Files->check();
$this->Menu->Build();
$this->TPL->print();
}
}
// $Module - создается вне класса, хотя можно создавать и в классе Main - без разницы
public function loadModule($className,&$Module) {
switch($className) {
case "MD5Files":
$this->MD5Files=$Module;
break;
}
}
private function some() {
$this->MD5Files->check();
$this->Menu->Build();
$this->TPL->print();
}
}
Но тут ещё одно НО... Те же MD5Files, TPL, etc. требуют данные, которые будут определены в Main.. А получить доступ из MD5Files к Main, а тем более к другим я считаю вообще нереальным... В общем тоже гон получается... Слишком большая путаница...
Вот я и не знаю.. Есть ли какое-либо интересное извращение, чтобы разбить это все по объектам (ну в объект хапихнуть методы, свойства и т.д.) Или же оставить все по простому и писать все в одном классе, а для методов просто префиксы использовать??
Хотелось бы чтоб конечно как мне хочется) Так по крайней мере удобней и нагляднее...
1. Ты делаешь один класс, но распределённый по файлам. Кажется, в пыхе, если в описании класса ты сделаешь инклюд, то всё заинклюженое будет рассматриваться как нутро класса. Т.о. ты как-то разобьёшь по функциональности свою систему.
2. Делаешь сколько нужно разных классов, а в главном классе, при инициализации, вызываешь конструкторы ведомых классов, так чтобы экземпляры хранились в $_GLOBALS. А дальше через глобалс[имя] рулишь в ведоміх классах...
А насчет второго.. Вполне подходит. Посмотрим что другие скажут
Но я все больше склоняюсь к тому чтобы все запихнуть в один класс.. Хоть и не удобно так, блин(((
Гадство. И правда не работает.
Я так подумал.. Короче перепроектирую щас все нафиг)) Все запихну в один класс. А уже потом в зависимости от задачи буду строить иерархию создания потомков.. Наверно сейчас это наилучший вариант будет..
Хотя.. Аааааа)) Мой моск))) Совсем запутался %)
Цитата: UAS
Первый пашет) С извратом) Но пашет.. $GLOBALS передавать по ссылке надо в конструктор каждого класса.
Не понял? Что пашет и зачем по ссылке?
Ладно. Тему можно закрыть.. Я вообщем сам намутил чего-то. Перепроектирую. Но если что, советы по первому посту я бы послушал
А его передавать никуда не нужно. Это глобальный массив, который доступен из любой точки программы. Только он без подчёркивания пишется. Я первый раз обшибся :)
Цитата: UAS
Я вообщем сам намутил чего-то. Перепроектирую. Но если что, советы по первому посту я бы послушал
Можеш вот это почитать: http://ooad.asf.ru/Pattern.aspx?IdKat=7&IdPat=44
Сложно, но вроде бы похоже на твой случай.
Неудобно спать на потолке и когда звонят в дверь и спрашивают "папа, это ты?". Кажется, так. :)
Код:
<?php
/**
* Разбить по файлам. За названия не пинайте, спать хочу.
*/
class Menu
{
public function build(Menu $obj)
{
//Тут работаем с ним, как с своим. Если он нужен во всё классе, то передаём в конструкторе
}
}
class Check
{
}
class Main
{
/**
*
* @var Menu
*/
protected $menu;
/**
*
* @var Check
*/
protected $check;
public function __construct()
{
$this->menu = new Menu();
$this->check = new Check();
}
//Предположим, что тебе в меню нужен этот класс (не знаю для чего, но тебе виднее)
public function foo()
{
$menu = $this->menu->build($this);
}
}
/**
* Разбить по файлам. За названия не пинайте, спать хочу.
*/
class Menu
{
public function build(Menu $obj)
{
//Тут работаем с ним, как с своим. Если он нужен во всё классе, то передаём в конструкторе
}
}
class Check
{
}
class Main
{
/**
*
* @var Menu
*/
protected $menu;
/**
*
* @var Check
*/
protected $check;
public function __construct()
{
$this->menu = new Menu();
$this->check = new Check();
}
//Предположим, что тебе в меню нужен этот класс (не знаю для чего, но тебе виднее)
public function foo()
{
$menu = $this->menu->build($this);
}
}
Я бы даже сделал иначе. При создании коммутационного класса присваивал нескольким свойствам как значение ссылку на созданные объекты (которые в объявлении коммутационного объета можно сразу и объявить, кстати). Нам ведь не надо постоянно менять эти объекты местами.
Прошу заметить автора топика, что в PHP ниже версии 5 (т.е. 3-4) ссылку на объект надо давать ЯВНО. В PHP5 объект и есть ссылка на самого себя. Смотри http://www.php.net/manual/ru/language.oop5.php
Да я собсно в общем показал, как идею... А то 3 класса в одном это как-то не так... :)
ЗЫ: в объявлении свойств класса Main у $menu и $check не должны быть protected. Должны быть public
Я всё делаю через get/set, поэтому у меня все свойства protected/private, но решать тебе.
shaelf, +1. get/set - это пять! =)
Да без них просто геморойней. Т.к. если эти класы используются больше, чем в одном месте и понадобится как-то модифицировать/проверять при чтении/записи, то понадобится изменять в тех местах, где они используются (даже если переделывать на get/set), а тут сразу всё предусмотренно.
да и валидацию данных можно проводить, так что всякую фигню не подпихнёшь :)
Цитата: shaelf
Да без них просто геморойней. Т.к. если эти класы используются больше, чем в одном месте и понадобится как-то модифицировать/проверять при чтении/записи, то понадобится изменять в тех местах, где они используются (даже если переделывать на get/set), а тут сразу всё предусмотренно.
А мне лень писать для каждого свойства get/set методы. Я сделал родительский класс
Код:
ЗЫ. Для тех кто еще не знает про __get/__set методы - обязательно почитайте.
В BaseClass они у меня матерятся об ошибках.
Тоже вариант))