Мне интересно, возможно ли в PHP заставить класс защитить свой конструктор как часть шаблона проектирования.
До сих пор я пытался реализовать его с помощью интерфейсов и абстрактных классов, но, похоже, это не работает. Я хочу, чтобы все мои классы обслуживания были синглетонами, и я достигаю этого (до некоторой степени), защищая конструктор. Как я могу обеспечить это?
Можно сделать конструктор защищенным.
Вот пример для одноэлементного шаблона:
<?php
class Test {
private static $instance = null;
protected function __construct()
{
}
public static function getSingleton()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
}
// Does work
$test = Test::getSingleton();
// doesn't work
$test = new Test();
Для «сервисов» используйте контейнер внедрения зависимости.
В качестве примера я использую простую контейнерную реализацию, но их гораздо больше.
http://container.thephpleague.com/2.x/getting-started/
<?php
interface ExampleServiceInterface {
}
class ImplementationA implements ExampleServiceInterface {
}
class ImplementationB implements ExampleServiceInterface {
}
$container = new League\Container\Container;
// add a service to the container
$container->share(ExampleServiceInterface::class, function() {
$yourChoice = new ImplementationA();
// configure some stuff? etc
return $yourChoice;
});
// retrieve the service from the container
$service = $container->get(ExampleServiceInterface::class);
// somewhere else, you will get the same instance
$service = $container->get(ExampleServiceInterface::class);
Вы можете заставить его, бросив исключение?
final class Foo {
private static $meMyself = null;
protected function __construct() {
if(!is_null(Foo::$meMyself)) {
throw new \Exception("ouch. I'm seeing double");
}
// singleton init code
}
}
но там против говорит: люди, которые используют его, вероятно, будут иметь доступ к вашим методам / коду и могут просто изменить его.