将实例对象传输到 class
Transfer of an instanced object into a class
我想知道将实例化对象传输到另一个 class 以供本地使用的最佳方法是什么。我也很好奇这是否会对内存使用产生影响。
我想了想,主要有两种方式:
1.) 通过引用 $GLOBALS 来传输实例对象:
class UserLogHandler {
public function __construct() {
$this->DB = $GLOBALS['DB'];
$this->Security = $GLOBALS['Security'];
}
public function doSomeWork() {
$this->DB->someMethod;
}
}
或
2.) 交接转账:
class UserLogHandler($DB,$Security) {
public function doSomeWork() {
$DB->someMethod;
}
}
在我看来,选项 2 可能更适合复杂的环境,尽管我觉得选项 1 更有吸引力。无论如何,我更喜欢技术 and/or 逻辑解释为什么使用一个选项而不是另一个。如果有其他更好的选择也请告诉我。
提前致谢并致以最良好的祝愿,
托马斯
这确实是个好问题。我会说这取决于你的需要。让我们一一分析您的选择。
开始之前,请记住您的对象应该始终是一个完整的对象。它不应该有一个不完整的状态。可以参考这篇文章加深理解https://matthiasnoback.nl/2018/07/objects-should-be-constructed-in-one-go/
1.) 通过引用 $GLOBALS 来传输实例对象:
切勿使用此类方法,因为它们会造成混淆。 $GLOBALS 无法告诉您特定变量是在何处以及如何创建的,因此您永远无法确定该变量是否存在或它包含什么。我建议你使用依赖注入
use DB;
use Security;
class UserLogHandler
{
public function __construct(DB $DB, Security $Security)
{
$this->DB = $DB;
$this->Security = $Security;
}
public function doSomeWork()
{
$this->DB->someMethod;
}
}
了解您现在如何确定 $DB 和 $Security 从何处注入以及它们持有什么。您甚至可以使用 Security $Security
.
等类型指示来强制执行变量类型
当您的 class 严重依赖于特定变量时,此方法会派上用场。例如模型 class 始终需要 DB 适配器,或者 PDF 生成器库本质上需要 PDF class。
2.) 交接转移
这按您预期的方式工作,但我认为您在定义它时犯了错误。你需要像下面这样写。
class UserLogHandler
{
public function doSomeWork($DB, $Security)
{
$DB->someMethod;
}
}
当您仅需要特定函数中的特定变量时,此方法会派上用场。例如,就像我们需要从某个特定条件下的模型中获取记录一样。所以我们可以在函数中传值,根据值得到结果。
use DB;
use Security;
class UserLogHandler
{
public function __construct(DB $DB, $Security)
{
$this->DB = $DB;
$this->Security = $Security;
}
public function doSomeWork($value)
{
if ($value = 'something') {
$this->DB->someMethod;
}
}
}
如您所见,这两种方法都可以结合使用。这只取决于你的要求
我想知道将实例化对象传输到另一个 class 以供本地使用的最佳方法是什么。我也很好奇这是否会对内存使用产生影响。
我想了想,主要有两种方式:
1.) 通过引用 $GLOBALS 来传输实例对象:
class UserLogHandler {
public function __construct() {
$this->DB = $GLOBALS['DB'];
$this->Security = $GLOBALS['Security'];
}
public function doSomeWork() {
$this->DB->someMethod;
}
}
或 2.) 交接转账:
class UserLogHandler($DB,$Security) {
public function doSomeWork() {
$DB->someMethod;
}
}
在我看来,选项 2 可能更适合复杂的环境,尽管我觉得选项 1 更有吸引力。无论如何,我更喜欢技术 and/or 逻辑解释为什么使用一个选项而不是另一个。如果有其他更好的选择也请告诉我。
提前致谢并致以最良好的祝愿, 托马斯
这确实是个好问题。我会说这取决于你的需要。让我们一一分析您的选择。
开始之前,请记住您的对象应该始终是一个完整的对象。它不应该有一个不完整的状态。可以参考这篇文章加深理解https://matthiasnoback.nl/2018/07/objects-should-be-constructed-in-one-go/
1.) 通过引用 $GLOBALS 来传输实例对象:
切勿使用此类方法,因为它们会造成混淆。 $GLOBALS 无法告诉您特定变量是在何处以及如何创建的,因此您永远无法确定该变量是否存在或它包含什么。我建议你使用依赖注入
use DB;
use Security;
class UserLogHandler
{
public function __construct(DB $DB, Security $Security)
{
$this->DB = $DB;
$this->Security = $Security;
}
public function doSomeWork()
{
$this->DB->someMethod;
}
}
了解您现在如何确定 $DB 和 $Security 从何处注入以及它们持有什么。您甚至可以使用 Security $Security
.
当您的 class 严重依赖于特定变量时,此方法会派上用场。例如模型 class 始终需要 DB 适配器,或者 PDF 生成器库本质上需要 PDF class。
2.) 交接转移
这按您预期的方式工作,但我认为您在定义它时犯了错误。你需要像下面这样写。
class UserLogHandler
{
public function doSomeWork($DB, $Security)
{
$DB->someMethod;
}
}
当您仅需要特定函数中的特定变量时,此方法会派上用场。例如,就像我们需要从某个特定条件下的模型中获取记录一样。所以我们可以在函数中传值,根据值得到结果。
use DB;
use Security;
class UserLogHandler
{
public function __construct(DB $DB, $Security)
{
$this->DB = $DB;
$this->Security = $Security;
}
public function doSomeWork($value)
{
if ($value = 'something') {
$this->DB->someMethod;
}
}
}
如您所见,这两种方法都可以结合使用。这只取决于你的要求