Выбор класса, в зависимость от версии

PassExcel

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

Отталкиваюсь от мыслей:
1) Написать главный класс и все методы реализовать в нем.
2) Написать дополнительные классы, на каждую версию (например разница кода только для мажорных версий)
3) Написать класс оболочку, которая при вызове смотрит сначала метод у дополнительных классов, и если его нет, использует метод основного класса.


Вот собственно, чтобы было сделано:

Непосредственно сам вызов

PHP:
<?php
..//include
$plesk = new Plesk();
$plesk->setVersion(7);
$plesk->login();
?>
Класс оболочка:

PHP:
<?php

Class Plesk {

	private $subclass  = null;
	private $mainclass = null;


	function __construct() {
		$class = __CLASS__.'_main';
		$this->mainclass = new $class();
	}


	function setVersion($version) {
		if (class_exists(__CLASS__.'_'.$version)) {
			$class   = __CLASS__.'_'.$version;
			$this->subclass = new $class();
		}
	}


	function __call($method, $arg) {
		if ($this->subclass !== null && method_exists($this->subclass, $method)) {
			return $this->subclass->$method($arg);
		} elseif (method_exists($this->mainclass, $method)) {
			return $this->mainclass->$method($arg);
		} else {
			return false;
		}
	}
}
?>


Основной класс
PHP:
<?php
class Plesk_main extends Plesk {
	function __construct() {

	}
	function login($data) {
		echo('main login');
	}
}
?>
Класс для седьмой версии
PHP:
<?php
class Plesk_7 extends Plesk {
	function __construct() {

	}
	function login($data) {
		echo('login for version [7]');
	}
}
?>

В Plesk_main я описываю все методы по дефолту.
В Plesk_7 - я описываю только различающиеся методы. Что в отличии от паттерна стратегии, позволяет не копировать остальные идентичные методы.


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

Adelf

Administrator
Команда форума
Ты заново придумал наследование? :)
 

PassExcel

Новичок
Не уверен. Я через __call в родителе определяю, чей метод из дочерних классов будет использован.
 

Dovg

Продвинутый новичок
Фабрика/фабричный метод

PHP:
 Plesk::createByVersion(42)->login();
 Plesk::createByVersion(25)->login();
 

Adelf

Administrator
Команда форума
делаем Plesk. Реализовываем там все.
Делаем Plesk_7, наследуем от Plesk. Переопределяем там методы нужные.
С другими версиями также.

Потом делаем фабричную функцию.. ну или метод.
PHP:
functionGetPlesk($version = null)
{
 //и создаем здесь обьект нужного класса, в зависимости от версии. Ну или по дефолту Plesk.
}
 

tz-lom

Продвинутый новичок
полная хрень,для этого есть наследование и если так угодно,фабрика как порождающий паттерн
выброси из головы паттерны и прочитай что такое ООП ещё раз,этот код фееричен по своей бесполезности
P.S.
пока писал ответ выше уже написали что надо делать и как
 

PassExcel

Новичок
Спасибо, еще раз покопался в статьях про наследование. Родился такой код

Главный скрипт, фабричная функция и работа с объектом плеска.

PHP:
<?php
include 'Plesk.class.php';
include 'Plesk_7.class.php';

function getPlesk($version = null) {
	if ($version != null && class_exists('Plesk_'.$version)) {
		$class = 'Plesk_'.$version;
		return new $class();
	}
	return new Plesk();
}

$plesk = getPlesk(7);
$plesk->login();
?>

Собственно предок плеска, в котором будет реализован весь функционал
PHP:
<?php
class Plesk {
    function __construct() {
    }
    function login() {
        echo('main login');
    }
}
?>
Потомок плеска для 7 версии, в котором будут только методы для переопределения
PHP:
<?php

class Plesk_7 extends Plesk {
    function __construct() {
		parent::__construct();
    }

    function login() {
        echo('version 7 login');
    }

}
?>

Что скажете насчет этого кода?

Хотелось бы фабричную функцию запихнуть в сам класс Plesk, но пока не получается.

А использовать такой вид не хочется
PHP:
Plesk::createByVersion(42)->login();
 

Dovg

Продвинутый новичок
>но пока не получается.
Почему?
>А использовать такой вид не хочется
почему?

PHP:
class Plesk_7 extends Plesk {
    function __construct() {
        parent::__construct();
    }
Не кажется, что конструктор у потомка неуместен, если он ничего не делает?
 

Gas

может по одной?
почему ничего не делает, он вызывает конструктор парента, автоматически это же не происходит.
 

Dovg

Продвинутый новичок
2Gas:
гхм...
Код:
dovg@thinker:/tmp/docs/test$ php -a
Interactive mode enabled

<?php

class testclassa 
{

public function __construct()
{
echo 'I am testclass A';
}
}

class testclassb extends testclassa {}

$b = new testclassb();

I am testclass A
 

Gas

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

хотя и сам такие конструкции пишу
PHP:
function __construct() 
{
   parent::__construct();
}
лично мне, так наглядней
 

PassExcel

Новичок
Не кажется, что конструктор у потомка неуместен, если он ничего не делает?
Код брал отсюда
http://ru2.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor


Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required.
Странно, что в документации написано одно, а на самом деле происходит другое.
 

tz-lom

Продвинутый новичок
PassExcel
читай внимательнее,если конструктор перекрыт,то родительский не вызывается,однако если перекрыт то происходит спуск по родителям и первый найденный конструктор будет вызван
 
Сверху