У меня есть вопрос, который больше похож на вопрос дизайна. У меня есть класс, который определяет кучу функций. Однако я хочу, чтобы поведение некоторых функций изменялось во время выполнения или, по крайней мере, работало как интерфейс плагина во время разработки. например:
class MyClass {
public function doSomething();
}
$obj = new MyClass();
// PSEUDO CODE
$obj->doSomething = doSomethingElse;
$obj->doSomething(); // does something else
У меня были разные идеи, как реализовать что-то подобное в «реальном» коде. Однако я не совсем уверен, что это правильный путь. Сначала я подумал, что могу использовать интерфейс для этой цели.
interface IDoSomethingInterface {
public function doSomething();
}
class DoSomethingClass implements IDoSomethingInterface
{
public function doSomething()
{
// I do something!
}
}
class DoSomethingElseClass implements IDoSomethingInterface
{
public function doSomething()
{
// I actually do something else!
}
}
class MyClass {
public doSomething(IDoSomething $doSomethingProvider)
{
$doSomethingProvider->doSomething();
}
}
$obj = new MyClass();
$doSomethingProvider = new DoSomethingClass();
$doSomethingElseProvider = new DoSomethingElseClass();
$obj->doSomething($doSomethingProvider); // I do something!
$obj->doSomething($doSomethingElseProvider); // I do something else!
Этот подход можно расширить, чтобы не передавать провайдеру doSomething в качестве параметра, а задавать его либо как член объекта, либо даже как член класса. Однако мне не понравилось, что мне нужно создать экземпляр класса n, который даже не содержит единственной переменной-члена, и единственным методом может быть функция статического класса. Там просто нет необходимости в объекте в этой точке Imo.
Затем я собирался использовать функциональные переменные, но тогда я выпал из ООП, что мне тоже не понравилось. Мои вопросы: какой лучший способ реализовать систему, как я описал? Какой подход вы бы попробовали или использовали? Есть ли что-то очевидное, о чем я мог бы и не подумать? Или я должен просто придерживаться подхода интерфейса, и мое плохое предчувствие насчет создания объектов «без тела» - просто бесценное занятие ?! Мне интересно ваши ответы!
Edit:
Поскольку мне действительно интересно выяснить, является ли это (или должно быть) государством или моделью стратегии, я более подробно расскажу о реализации. У меня есть базовый класс коллекций, из которых я получаю различные конкретные реализации. Я хочу иметь возможность выбрать один элемент из любой конкретной реализации - однако я хочу иметь возможность динамически изменять способ выбора этого элемента из коллекции, например:
class MyCollection implements Countable, ArrayAcces, Iterator
{
// Collection Implementation
public function select(ISelectionStrategy $strategy)
{
return $strategy->select($this);
}
}
interface ISelectionStrategy
{
public function select(MyCollection $collection);
}
class AlphaSelectionStrategy implements ISelectionStrategy
{
public function select(MyCollection $collection);
{
reset($collection);
if (current($collection))
return current($collection);
else
return null;
}
}
class OmegaSelectionStrategy implements ISelectionStrategy
{
public function select(MyCollection $collection)
{
end($collection);
if (current($collection))
return current($collection)
else
return null;
}
}
class RandomSelectionStrategy implements ISelectionStrategy
{
public function select(MyCollection $collection)
{
if (!count($collection))
return null;
$rand = rand(0, count($collection)-1);
reset($collection);
while($rand-- > 0)
{
next($collection);
}
return current($collection);
}
}
$collection = new MyCollection();
$randomStrategy = new RandomSelectionStrategy();
$alphaStrategy = new AlphaSelectionStrategy();
$omegaStrategy = new OmegaSelectionStrategy();
$collection->select($alphaStrategy); // return first element, or null if none
$collection->select($omegaStrategy); // return last element, or null if none
$collection->select($randomStrategy); // return random element, or null if none
Это в основном то, чего я хочу достичь. Является ли это сейчас реализацией шаблона стратегии или шаблона состояния - хотя я использовал термин стратегия, потому что в любом случае он больше подходит. Насколько я понимаю, стратегия и структура государства в основном одинаковы, за исключением того, что их намерения различны. Ссылка, предоставленная Гордоном, гласит, что намерение шаблона состояния - «Разрешить объекту изменять свое поведение при изменении его внутреннего состояния», но здесь это не так. Я хочу сказать, чтобы мой класс MyCollection мог «использовать тот или иной алгоритм, чтобы дать мне элемент», а не «дать мне элемент, используя алгоритм, который вы определяете через свое собственное состояние». Надеюсь, что кто-то может прояснить это!
С уважением,
Daniel