Ниже приведен неправильный ответ, но я оставлю его для изучения другими (см. Ниже)
В ExampleA, вы можете использовать один и тот же Configэкземпляр для нескольких классов. Однако, если Configво всем приложении должен быть только один экземпляр, рассмотрите возможность применения шаблона Singleton, Configчтобы избежать нескольких экземпляров Config. И если Configэто Singleton, вы можете сделать следующее:
class ExampleA
{
private $config;
public function __construct()
{
$this->config = Config->getInstance();
}
}
$exampleA = new ExampleA();
В ExampleB, с другой стороны, вы всегда получите отдельный экземпляр Configдля каждого экземпляра ExampleB.
Какую версию вы должны применить, зависит от того, как приложение будет обрабатывать случаи Config:
- если каждый экземпляр
ExampleXдолжен иметь отдельный экземпляр Config, переходите к ExampleB;
- если каждый экземпляр
ExampleXразделяет один (и только один) экземпляр Config, используйте ExampleA with Config Singleton;
- если экземпляры
ExampleXмогут использовать разные экземпляры Config, придерживайтесь ExampleA.
Почему преобразование Configв синглтон неправильно:
Я должен признать, что я узнал о паттерне Singleton только вчера (читая книгу « First First», посвященную шаблонам проектирования). Наивно я пошел и применил его для этого примера, но, как многие отмечали, один путь - другой (некоторые были более загадочными и говорили только: «Вы делаете это неправильно!»), Это не очень хорошая идея. Итак, чтобы не допустить повторения той же ошибки, которую я только что совершил, ниже приведено краткое изложение причин, по которым паттерн Синглтон может быть вредным (на основе комментариев и того, что я обнаружил, погугляя)
Если ExampleAполучить собственную ссылку на Configэкземпляр, классы будут тесно связаны. Не будет никакого способа иметь экземпляр ExampleAдля использования другой версии Config(скажем, некоторого подкласса). Это ужасно, если вы хотите протестировать ExampleAс использованием экземпляра макета, Configпоскольку нет способа предоставить его ExampleA.
Предположение о том, что будет один, и только один, Configможет быть, имеет место сейчас , но вы не всегда можете быть уверены, что то же самое сохранится в будущем . Если в какой-то более поздний момент окажется, что несколько экземпляров Configбудут желательны, нет способа достичь этого без переписывания кода.
Даже если один-единственный-единственный экземпляр Configможет быть верным на всю вечность, может случиться так, что вы захотите использовать некоторый подкласс Config(хотя при этом у вас будет только один экземпляр). Но, поскольку код напрямую получает экземпляр с помощью getInstance()of Config, который является staticметодом, нет способа получить подкласс. Опять же, код должен быть переписан.
Тот факт, что ExampleAиспользует, Configбудет скрыт, по крайней мере, при просмотре только API ExampleA. Это может или не может быть плохой вещью, но лично я чувствую, что это чувствует себя недостатком; например, при ведении не существует простого способа выяснить, на какие классы будут влиять изменения, Configне рассматривая реализацию любого другого класса.
Даже если сам факт ExampleAиспользования Singleton Config не является проблемой сам по себе, он все равно может стать проблемой с точки зрения тестирования. Одиночные объекты будут нести состояние, которое будет сохраняться до завершения приложения. Это может быть проблемой при запуске модульных тестов, поскольку вы хотите, чтобы один тест был изолирован от другого (то есть выполнение одного теста не должно влиять на результат другого). Чтобы исправить это, объект Singleton должен быть уничтожен между каждым запуском теста (возможно, потребуется перезапустить все приложение), что может занять много времени (не говоря уже об утомительном и раздражающем).
Сказав это, я рад, что я сделал эту ошибку здесь, а не в реализации реального приложения. На самом деле, я подумывал переписать свой последний код, чтобы использовать шаблон Singleton для некоторых классов. Хотя я мог бы легко отменить изменения (все хранится в SVN, конечно), я все равно потратил бы впустую время, делая это.