[英]PHP chained class methods merged with other classes
我从一个例子开始。
模具类
<?php
class Mold {
public $current;
function merge($first, $second) {
$this->current = $first . $second;
return $this;
}
function phone() {
$this->current = '<a href="tel:' . $this->current . '">' . $this->current . '</a>';
return $this;
}
function __toString() {
return $this->current;
}
}
function mold() {
return new Mold();
}
在行动
这按预期工作。
echo mold()->merge('sada', 'asdsa')->phone();
我有一个或多个类,它们的方法也希望可以使用。
插件类
class MyPlugin {
function link() {
// Code
}
function currency($number) {
// Code
}
}
class MyPlugin2 {
// Other methods
}
梦代码
以下事件的确切变化可能没有任何意义。 无论如何,我打算做以下事情。
echo mold()->merge('sada', 'asdsa')->currency(45)-link();
mold()
创建一个新的Mold
类实例。 Mold
类使用的chain merge()
。 Mold
类中不存在currency()
或link()
方法。 而是应从其中一个插件加载它们。 Mold
类注意。 从技术上讲,您可以使用__call()
。 您的“主”类可以包含/跟踪一组插件实例,并且可以查找和委托任何未知的方法调用(如果在插件中可用)。
我不会推荐这个。 流利的API通常很脆弱,即使只有一类也可能带来不便。 使多个类参与流利的调用可能很快就会造成混乱。 混乱,甚至IDE也无法帮助您(或其他使用代码的人),因为它无法掌握所有发生的魔术。
我强烈建议您研究此类API的替代模式。
一个解决方案可能是组成当前的Mold
对象并传递两个插件实例,以便它可以在其方法上使用它们,如下所示:
<?php
class Mold {
public $current;
public function __construct(Plugin1 $plugin1, Plugin2 $plugin2) {
$this->plugin1 = $plugin1;
$this->plugin2 = $plugin2;
}
public function merge($first, $second) {
$this->current = $first . $second;
return $this;
}
public function phone() {
$this->current = '<a href="tel:' . $this->current . '">' . $this->current . '</a>';
return $this;
}
public function __toString() {
return $this->current;
}
public function link() {
$this->plugin1->link();
return $this;
}
}
function mold() {
return new Mold(new Plugin1(), new Plugin2());
}
另一个解决方案是创建某种MoldHandler
类,该类将Mold
对象作为属性与其他插件一起使用,可以直接在其中使用。
public class MoldHanlder {
protected $mold;
protected $plugin1;
protected $plugin2;
public function __contruct($mold, $plugin1, $plugin2) {
$this->mold = $mold;
$this->plugin1 = $plugin1;
$this->plugin2 = $plugin2;
}
public function merge() {
$this->mold = $this->mold->merge();
return $this;
}
public function link() {
$foo = $this->plugin1->method();
return $this;
}
...
}
您也可以只实例化construct
的类,但是如果您打算编写单元测试,则依赖注入是解决之道
我认为第一种方法更好,因为您避免自己重新编写Mold类的一些代码,这是不必要的
注意,这是一个非常原始的解决方案,只是为了让您更好地理解我会选择的想法
有趣的想法。
解决我所想到的问题的一种方法是使用注释中建议的@ vivek_23之类的特征 。
这是工作原理的完整示例
<?php
// Core methods
class MoldCore {
public $current;
function merge($first, $second) {
$this->current = $first . $second;
return $this;
}
function phone() {
$this->current = '<a href="tel:' . $this->current . '">' . $this->current . '</a>';
return $this;
}
function __toString() {
return $this->current;
}
}
// Plugin 1
trait Plugin1 {
public function yaay() {
$this->current .= ' Plugin1 yaay';
return $this;
}
}
// Plugin 2
trait Plugin2 {
public function hello() {
$this->current = str_replace('Plugin1', 'Modified', $this->current);
return $this;
}
public function world() {
$this->current .= ' Plugin2 world';
return $this;
}
}
// Glue plugins with MoldCore
class Mold extends MoldCore {
use Plugin1, Plugin2;
}
$mold = new Mold();
echo $mold->merge('sada', 'asdsa')->phone()->yaay()->hello();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.