Я бы предложил другой подход к этому. При использовании разных методов для каждого четного типа вам потребуется написать повторяющийся код, что в конечном итоге приведет к дорогостоящему поддерживаемому коду и подверженности ошибкам (даже копирование/вставка подвержена ошибкам!), И я видел это в некоторых проектах, чтобы доказать это).
Во-первых, статические вызовы должны быть ограничены (или главным образом), когда методы не требуют хранения данных в классах; статический метод не должен устанавливать ничего, меньше данных, которые будут использоваться экземплярами самого класса. Поэтому вы должны использовать шаблон singleton.
Во-вторых, если у вас должно быть много типов событий, каждый из них должен иметь свой соответствующий специализированный класс. Объектно-ориентированный дизайн идет от абстрактного к конкретному, общего к специализированному. Поэтому ваш Events
не должен знать, сколько или какого события он хранит, но должен оставить это вызывающему.Это позволит вам иметь более согласованный интерфейс.
Вот бы пример дизайна:
class Events {
static private $_instance;
static public function getInstance() {
// lazy loading of the class instance will not use unnecessary resources
if (null === self::$_instance) {
self::$_instance = new self(); // <-- valid PHP declaration
}
return self::$_instance;
}
// class members
protected $_events; // protected allows inheritance, use private to forbid it
// private constructor prohibit external instances to be created
private function __construct() {
$this->_events = array();
}
// (GETTER: methods that starts with 'get'...)
// use $year before $month for priority order ($month is more precise than $year)
public function getEvents($type, $year = null, $month = null) {
$_values = array();
// if we have any event of that type...
if (array_key_exists($type, $this->_events)) {
foreach ($this->_events[$type] as $event) {
// filter events to return... (if $year is null, $month is ignored)
if ((null === $year
|| (($year == $event->getYear())
&& (null === $month || $month == $event->getMonth())))) {
$_values[] = $event;
}
}
}
return $_values;
}
// (SETTER: methods that starts with 'add', 'set', etc.)
public function addEvent(AbstractEvent $event) {
if (!array_key_exists($event->getType(), $this->_events)) {
$this->_events[$event->getType()] = array();
}
$this->_events[$event->getType()][] = $event;
// returning $this allows chaining.
// While some argue the design of this, I personally like it
return $this;
}
}
Теперь у нас есть наш контейнер, мы будем нуждаться типы событий, первый у нас есть базовый класс:
abstract class AbstractEvent {
protected $_year; // again, protected to enable inheritance
protected $_month;
public function __construct($year, $month) {
// TODO : perform some argument check here
$this->_year = $year;
$this->_month = $month;
}
abstract public function getType();
public function getYear() { return $this->_year; }
public function getMonth() { return $this->_month; }
}
Тогда просто специализировать его (мы создаем два вида специализируются событий):
class MicrosoftEvent extends AbstractEvent {
const TYPE = 'Microsoft';
public function getType() { return self::TYPE; }
}
class LinuxEvent extends AbstractEvent {
const TYPE = 'Linux';
public function getType() { return self::TYPE; }
}
Добавление новых событий
Events::getInstance()
->addEvent(new LinuxEvent(2010, 7))
->addEvent(new MicrosoftEvent(2008, 8))
->addEvent(new MicrosoftEvent(2010, 2))
->addEvent(new LinuxEvent(2009, 1))
// ...
;
Получить события
// 1. get ALL Microsoft events
var_export(Events::getInstance()->getEvents(MicrosoftEvent::TYPE));
// 2. get all events for 'Linux' in 2010
var_export(Events::getInstance()->getEvents('Linux', 2010));
// 3. same as 1; $month will be ignored, because $year is not specified
var_export(Events::getInstance()->getEvents('Microsoft', null, 6));
// 4. returns empty array because unknown event type
var_export(Events::getInstance()->getEvents('Foo'));
Как вы можете видеть, накладные расходы на дизайн класса является немного более сложным, но API является гораздо более последовательным после этого. Хорошая конструкция должна применять шаблон повторного использования, и это выполняется здесь. Надеюсь это поможет.
****** EDIT ****, так как ваш вопрос изменился, вот отредактированное решение. Это гораздо меньше, но все-таки следовать той же базовой конструкции:
class Events {
static private $_events = array();
// GETTER
static public function getEventType($type) {
// if we have any event of that type...
if (!array_key_exists($type, self::$_events)) {
$eventClass = $type . 'Event';
self::$_events[$type] = new $eventClass();
}
return self::$_events[$type];
}
}
Тогда наш базовый тип события класса
abstract class AbstractEvent {
abstract public function getType();
public function getIdentifier($year, $month) {
return $this->getType().str_pad((int) $month, 2, '0', STR_PAD_LEFT).str_pad((int) $year, 4, '0', STR_PAD_LEFT);
}
}
Теперь мы специализироваться типы
class MicrosoftEvent extends AbstractEvent {
const TYPE = 'Microsoft';
public function getType() { return self::TYPE; }
}
class LinuxEvent extends AbstractEvent {
const TYPE = 'Linux';
public function getType() { return self::TYPE; }
}
Затем мы тестируем Результаты
var_export(Events::getEventType(MicrosoftEvent::TYPE)->getIdentifier(2008, 6));
var_export(Events::getEventType(LinuxEvent::TYPE)->getIdentifier(2010, 2));
var_export(Events::getEventType('Microsoft')->getIdentifier('2009', '08'));
@stereofrog - Good p oint. Моя цель - создать класс, который использует один и тот же набор переменных для каждой статической функции. Однако каждая статическая функция предоставляет переменные класса разные статические значения. Является ли этот подход разумным решением моей цели? Надеюсь, что это не слишком расплывчато. – JMC
Я могу строго рекомендовать этот отличный учебник по классам, http://www.amazon.co.uk/Objects-Patterns-Practice-Experts-Source/dp/143022925X/ref=wl_it_dp_o?ie=UTF8&coliid=I2NUYS3JDGG7PU&colid=1478EBZ835RZN –
@ acidjazz: Ваше описание вместе с примером, который вы предоставили, к сожалению, имеет мало смысла для меня, и я подозреваю, что это неправильный подход. Не могли бы вы подробнее рассказать об использовании/использовании «событий класса»? – VolkerK