[英]Static reference of a class object
我已经编写了几个类,使用时都需要实例化。
我的目标是在尝试在实例化的类之间创建动态访问时能够拥有一个完美的组织。
在一个类中,它将基于刚刚执行的操作而调用几种方法。 这些方法中的一种将是其他类的方法。 (当前为静态方法)我将编辑这些行以控制类之间的行为。
我的意思是动态的,如果其中一种静态方法不可用或以后将可用,那么它只是执行另一种方法以在内部完成任务。
我的问题是有关适当的OOP的问题。 我不确定是否有更好的方法,或者我在做什么会导致问题。 虽然,它工作得很好。
我在下面准备了一个例子。 其中,是代表,不是实际情况。 执行文件一是一种情况,执行文件二是另一种情况。
executingFileOne.php
require_once 'login.php';
$login = new Login();
require_once 'serverData.php';
$servDat = new serverData();
//blah blah blah
executingFileTwo.php
require_once 'serverData.php';
$servDat = new serverData();
//blah blah blah
的login.php
class Login {
private static $thisClass = null;
public function __construct(){
//Get and set user data.
self::setStaticClass($this);
}
public static function setStaticClass(&$inputClass){
self::$thisClass = $inputClass;
}
//Methods Methods Methods
//---Methods Executed by class at specific times---------------
// - - - Used to get input from other classes
//Methods Methods Methods
//-------------------------------------------------------------
//---Methods for other classes.--------------------------------
// - - - Used to output data to other classes
public static function getUserID(){
die('Test'.self::$thisClass->userID);
}
//Methods Methods Methods of other classes.
//-------------------------------------------------------------
}
serverData.php
class serverData {
private static $thisClass = null;
public function __construct(){
//work work work
//an IF statement detected needing to register userID on serverData
$this->registerOnServer();
//work work work
self::setStaticClass($this);
}
//Methods Methods Methods
public function registerOnServer(){
//work work work
$this->userID = $this->getUserID();
//add userID to registration data.
}
//---Methods Executed by class at specific times---------------
// - - - Used to get input from other classes
private function getUserID(){
if (class_exists('Login')) {
return Login::getUserID();
} else {
return 0;
}
}
//-------------------------------------------------------------
//---Methods for other classes.--------------------------------
// - - - Used to output data to other classes
//Methods Methods Methods of other classes.
//-------------------------------------------------------------
}
这是使用静态类时的几个问题之一,并且由于偷偷摸摸的自注册和使用现场的强耦合而变得更加复杂。 目前,对于这个问题,我普遍知道的“最佳”解决方案(我鼓励使用的一种解决方案)是使用依赖注入。
此外,在DI之上使用IoC(控制反转)容器可以使所有内容连接在一起并管理使用寿命是理智的过程。 ( 不要恢复到一个Service Locator模式除了在非常特殊的情况或DI +国际奥委会beautiy丢失!)
尽管使用非正式的鸭子式“接口”就足够了,但是使用编码接口有助于分类-并且IoC容器经常(但并非总是)能够注册和解析组件。
// This is the service (interface) that different components will provider
inteface ILogin {
public function getUserID ();
}
// Primary component (implementation) for the login service (interface)
class Login implements ILogin {
// Note:
// Constructor does NOT "register itself statically"; even when using
// an approach similar to the original, use a proper Singleton Design.
public function getUserID () { /* .. */ }
}
// Alternative/mock component (implementation) for the login service (interface)
class NoLogin implements ILogin {
public function getUserID () { return 0; }
}
// Class (possibly also a component) that uses the login service dependency
class ServerData {
// Constructor-based DI; the components are supplied as arguments
// (There is also property-based DI.)
public function __constructor(ILogin $login) {
$this->login = $login;
}
// Later on we use the service
// (It is a bit silly just to proxy the service, which should be
// injected elsewhere as required, but this mirrors the original.)
public function getUserID () {
// If not using a "mock service", then guard $this->login for null
// because it is now an optional dependency; the appropriate approach
// will vary based upon specific use-case.
return $this->login->getUserID();
}
}
然后稍后:
// File 1-
// Note how dependency is "injected" into the server data
$servDat = new ServerData(new Login());
// File 2-
// A different dependency providing the same contract/service is used
$servDat = new ServerData(new NoLogin());
// Or, if ServerData guards usage and the service is "optional"
// $servDat = new ServerData(null);
因此,这是DI的一种形式(尽管通用术语是IoC,DI是其中的一种实现),它的核心-简单,但不是很令人兴奋,并且可能变得乏味。 同样,即使依赖项已被移出立即使用站点之外,它们仍然在创建实例并手动注入组件的使用者上有效地进行了硬编码。
现在,具有DI + IoC的魔力适合什么地方? 组件已注册到IoC容器中,并且IoC容器用于实例化对象-这样的容器足够智能,可以自动解决 DI依赖关系。 那么File#1和File#2之间的唯一区别是它们使用略有不同的IoC配置(一个用于ILogin服务,一个使用Login,另一个使用NoLogin)。
IoC的其他有用功能是可以配置对象生存期。 在这种情况下,Login组件(完成登录服务)可能是每个请求的实例,实际上是“单一行为”-区别在于它不能在请求之间泄漏, 并且 Login组件现在与ServerData类松散耦合。
IoC容器还有很多其他内容-请参阅PHP DI ,其中似乎有相当不错的介绍。 请注意,可以使用上面介绍的相同的 DI就绪代码(在PHP-DI中)来进行组件解析。 (错误是免费的。)
我的一个朋友向我展示了一个比我更好的选择。 可能不是正确的解决方案,但是更好。
看到我实例化我的类,并且可以通过全局调用变量来简单地访问其他类中的。 而不是创建任何静态的东西。
例如:
require_once 'login.php';
$login = new Login();
require_once 'serverData.php';
$servDat = new serverData();
//blah blah blah
class Login {
public function __construct(){
//Get and set user data.
}
//Methods Methods Methods
//---Methods Executed by class at specific times---------------
// - - - Used to get input from other classes
//Methods Methods Methods
//-------------------------------------------------------------
//---Methods for other classes.--------------------------------
// - - - Used to output data to other classes
public static function getUserID(){
die('Test'.$this->userID);
}
//-------------------------------------------------------------
}
class serverData {
public function __construct(){
//work work work
//an IF statement detected needing to register userID on serverData
$this->registerOnServer();
//work work work
}
//Methods Methods Methods
public function registerOnServer(){
//work work work
$this->userID = $this->getUserID();
//add userID to registration data.
}
//---Methods Executed by class at specific times---------------
// - - - Used to get input from other classes
private function getUserID(){
global $login;
if ($login != null) {
return $login->getUserID();
} else {
return 0;
}
}
//-------------------------------------------------------------
//---Methods for other classes.--------------------------------
// - - - Used to output data to other classes
//Methods Methods Methods
//-------------------------------------------------------------
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.