首页 > 编程语言 >php中的组合模式

php中的组合模式

时间:2022-11-21 13:37:45浏览次数:37  
标签:function 组合 模式 节点 add deep new php public

概念

 

当我们的一个对象可能代表一个单一的实体,或者一个组合的实体,但是仍然需要通过同样的方式被使用时,这种情形则适合使用组合模式的设计。

 

示例

一个表单类实例在处理其表单所有元素的方法与处理该表单自身实例方法相同,在调用方法 render() 时,会随之遍历它的所有子元素并对他们调用 render() 方法

<?php


interface RenderableInterface
{
public function render(): string;
}


/**
* 该组合内的节点必须派生于该组件契约。为了构建成一个组件树,
* 此为强制性操作。
*/
class Form implements RenderableInterface
{
/**
* @var RenderableInterface[]
*/
private $elements;

/**
* 遍历所有元素,并对他们调用 render() 方法,然后返回表单的完整
* 的解析表达。
*
* 从外部上看,我们不会看到遍历过程,该表单的操作过程与单一对
* 象实例一样
*
* @return string
*/
public function render(): string
{
$formCode = '<form>';

foreach ($this->elements as $element) {
$formCode .= $element->render();
}

$formCode .= '</form>';

return $formCode;
}

/**
* @param RenderableInterface $element
*/
public function addElement(RenderableInterface $element)
{
$this->elements[] = $element;
}
}

class InputElement implements RenderableInterface
{
public function render(): string
{
return '<input type="text" />';
}
}

class TextElement implements RenderableInterface
{
/**
* @var string
*/
private $text;

public function __construct(string $text)
{
$this->text = $text;
}

public function render(): string
{
return $this->text;
}
}

$form = new Form();
$form->addElement(new TextElement('Email:'));
$form->addElement(new InputElement());
$embed = new Form();
$embed->addElement(new TextElement('Password:'));
$embed->addElement(new InputElement());
$form->addElement($embed);

示例2

<?php

/**
* 组合模式抽象基类
*/
abstract class CompanyBase{
//节点名称
protected $name;

public function __construct($name){

$this->name = $name;
}

public function getName(){
return $this->name;
}

//增加节点
abstract function add(CompanyBase $c);

//删除节点
abstract function remove(CompanyBase $c);

//输出节点信息
abstract function show($deep);

//节点职责
abstract function work($deep);

}

/**
* 公司类
*/
class Company extends CompanyBase{
protected $item = [];

public function add(CompanyBase $c){
$nodeName = $c->getName();

if(!isset( $this->item[$nodeName] )){

$this->item[$nodeName] = $c;
}else{
throw new Exception("该节点已存在,节点名称:".$nodeName);
}
}

public function remove(CompanyBase $c){
$nodeName = $c->getName();

if(isset( $this->item[$nodeName] )){

unset($this->item[$nodeName]);
}else{
throw new Exception("该节点不存在,节点名称:".$nodeName);
}
}

public function show($deep = 0){
echo str_repeat("-",$deep).$this->name;
echo "<br>";

foreach($this->item as $value){
$value->show($deep+4);
}

}
public function work($deep = 0){

foreach($this->item as $value){
echo str_repeat(" ",$deep)."[{$this->name}]<br>";
$value->work($deep+2);
}
}

}

/**
* 人力资源部门
*/
class HumanResources extends CompanyBase{

public function add(CompanyBase $c){
throw new Exception("该节点下不能增加节点");
}

public function remove(CompanyBase $c){

throw new Exception("该节点下无子节点");
}

public function show($deep = 0){
echo str_repeat("-",$deep).$this->name;
echo "<br>";

}
public function work($deep = 0){

echo str_repeat(" ",$deep)."人力资源部门的工作是为公司招聘人才";
echo "<br>";
}

}

/**
* 商务部门
*/
class Commerce extends CompanyBase{

public function add(CompanyBase $c){
throw new Exception("该节点下不能增加节点");
}

public function remove(CompanyBase $c){

throw new Exception("该节点下无子节点");
}

public function show($deep = 0){
echo str_repeat("-",$deep).$this->name;
echo "<br>";

}
public function work($deep = 0){

echo str_repeat(" ",$deep)."商务部门的工作是为公司赚取利润";
echo "<br>";
}
}


$c = new Company("北京某科技公司");
$h = new HumanResources("人力资源部门");
$com = new Commerce("商务部门");
$c->add($h);
$c->add($com);

//天津分公司
//为了偷懒,分公司的部门直接copy母公司的
$c1 = new Company("天津分公司");
$c1->add($h);
$c1->add($com);
$c->add($c1);

//武汉分公司
$c2 = new Company("武汉分公司");
$c2->add($h);
$c2->add($com);
$c->add($c2);

//使用公司功能
$c->show();
$c->work();

 

总结组合模式的特点

  1. 必须存在不可分割基本元素;
  2. 组合后的物体仍然可以被组合。

 

标签:function,组合,模式,节点,add,deep,new,php,public
From: https://blog.51cto.com/u_6353447/5873660

相关文章

  • php中的模板模式
    概念 在模板模式(TemplatePattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。定义一个操作中的......
  • 设计模式的基本原则
    设计模式设计模式的世界丰富多彩,比如生产一个个「产品」的工厂模式,衔接两个不相关接口的适配器模式,用不同的方式做同一件事的策略模式,构建步骤稳定、根据构建过程的不同配置......
  • Laravel中用到的设计模式
    1:工厂模式 Auth::user()此处Auth这个类就是工厂中的方法,Auth是注册树中的别名。好处:类似于函数的封装,使对象有一个统一的生成(实例化)入口。当我们对象所对应的类的类名发......
  • php中使用swoole加速lumen项目-laravelS实战
    ​背景 公司项目严重依赖lumen系列,代码众多,重构困难,虽然访问量变大,性能问题越来越严重,急需要提升性能,于是找到了这个项目 ​​https://github.com/hhxsv5/laravel-s​​ ......
  • 饿汉模式,懒汉模式线程安全问题
    饿汉模式:上来不管三七二十一直接创建对象再说。饿汉模式创建方式:1.先创建一个私有的构造函数(防止其它地方直接实例化)2.定义私有变量3.提供公共的获取实例的方法pub......
  • PHP中max_execution_time设置不生效
     问题描述: max_execution_time设置了1秒,但是发现超过3秒的脚本还是跑。于是深入研究下max_execution_time不生效的原因。 官网描述: ​​https://www.php.net/manual/zh/......
  • PHP中self与static区别和联系
    ​ PHP官方也说过,大概意思是说self调用的就是本身代码片段这个类,static-PHP5.3加进来的只得是当前这个类,有点像$this的意思,static调用的是从堆内存中提取出来,访问的是当......
  • PHP中如何实现进程间通讯
    ​ 进程间通讯机制——IPC(Inter-Process-Communication)。为了使得php5可以使用共享内存和信号量,必须在编译php5程序时激活shmop和sysvsem这两个扩展模块。实现方法:在......
  • PHP一些基础语法,转菜鸟
    数组使用①:遍历关联数组for($arrayas$key=>$value){echo$key.'=>'.$value.PHP_EOL;}②:判断key是否存在boolarray_key_exists(key,array)③:去除(shift)......
  • 设计模式--创建型模式
    设计模式--创建型模式创建型模式,共五种:工厂方法模式(一个工厂类ReturnNew子类)、抽象工厂模式(一个厂一个子类)、单例模式(恶汉,懒汉)、建造者模式(组合)、原型模式(Cloneable浅......