当前位置: 首页 > 知识库问答 >
问题:

PHP 中的组合与聚合

甄德寿
2023-03-14

我在读一篇关于OOP中的关系、关联、组合、聚合等的文章。有些事情令人困惑

因此,在PHP中,我们调用以下代码组合

class A
{
  
}

class B
{
    public function __construct(protected A $a)
    {
    }
}

在阅读了几篇关于作文的文章后

以下是组成示例:

class B
{
    public A $a;
  
    public function __construct()
    {
        $this->a = new A();
    }
}

因此,根据我的理解,聚合意味着A类的对象可以存在于B类之外,而组合意味着A类生命周期的对象取决于B类。

我正确理解了吗?

共有1个答案

艾心远
2023-03-14

重要的是要记住,这些是关联类和对象的模式。

我要提出的第一点是,任何像“使用组合而不是继承”这样的总括规则都反映了一些缺失的上下文。如果合适,请使用继承

这些其他模式用于将类关联在一起。

聚合通常用于层次结构/父/子关系。

一个典型的例子是关联雇员和部门。

  • 存在员工对象
  • 员工“由部门拥有/成员”
  • 你可以说“部门Foo”聚合了0-N员工。

因此,为了对此进行建模,部门通常会有一个内部员工[]数组。

相反,员工可以在内部存储部门对象。这基本上符合两个类之间的关系,即Many

组合反映了更严格的父/子关系,其含义是ObjectA由1-N个对象b组成。

组合关系的经典示例是购物车,其中包含0-N个产品行项目。

假设Cart和Lineitem类,Cart将存储一系列Lineitem。

聚合和组合之间的主要区别在于,使用组合,如果一个购物车被销毁,那么所有相关的线性项目对象都应该被销毁。

对于聚合示例,如果删除了一个部门,这并不一定意味着所有聚合的雇员都将被删除,而是意味着删除一个部门只会破坏雇员和部门之间的关系,并且可能要求存储雇员的部门对象的变量为空,直到该雇员被分配到另一个部门,或者他们的雇佣关系结束。

实际上,由于PHP是页面范围的,所以变量和对象组合是短暂的,因此您不会真正在ORM之外找到很多情况,因为ORM使用了这些UML模式。数据需要持久化,通常这种持久化是通过某种RDBMS或Document数据库实现的,ORM将模拟表之间的关系,或者可能是层次结构。

对于您的示例:

这些foo/bar A/B示例没有语义意义或价值。示例#1中唯一的机制是,如果第一个对象不是ObjA,则无法构造ObjB。您提供的语法在PHP8中是新的,我一开始就错过了。

这个例子似乎更可能是:

class A
{
    private bSet = array();

    public function addB(B $b) {
       $this->bSet[] = new B($this);
    }  
}

class B
{
    private $a;

    public function __construct(A $a)
    {
        $this->a = $a;            
    }
}


// B shouldn't be made without a Parent A
$objA = new A();
$objA->addB();
$objA->addB();

然而,技术上没有什么能阻止你做一个B,因为构造函数总是公共的。

$objB = new B($objA);   

对于聚合,这将是一个更有可能的场景:

class A
{
    private bSet = array();

    public function addB(B $b) {
       $this->bSet[] = $b;
       $b->setA($this);
    }

    public function delB(B $b) {
        for ($i=0; $i < count($this->bSet); $i++) {
            if ($b === $this->bSet[$i]) {
                unset($this->bSet[$i];
                break;
            }
        }
    }  
}

class B
{
    private $a;

    public function setA(A $a) {
        if ($this->a) {
            $this->a->delB($this);
        }
        $this->a = $a;
    }

    public function getA() {
        return $this->a;
    }

}

$objA1 = new A();
$objA2 = new A();

$objB1 = new B();
$objB2 = new B();
$objB3 = new B();

$objA1->addB($objB2);
$objA2->addB($objB1);
$objA2->addB($objB3);
//Change $objB3's parent from A1 to A2.
$objB3->setA($objA1);

甲与乙相互独立,但仍有所有权。

我发现在PHP开发中更有实际价值的是依赖注入作为领先PHP框架(Symfony、Laravel)的基础,以及您在四人帮书籍、领域驱动设计或其他书籍和网站中找到的其他常见OOP设计模式的实现。

 类似资料:
  • 问题内容: 我试图理解这些术语的含义。我举了一些例子,例如: 汇总:Facebook 有一个 用户 组成:facebook 中的 每个用户 都有一个 会话。 协会:人们 使用 浏览器 但是我对 具有 和 使用我的 示例感到困惑。为什么不能是用户 使用 Facebook帐户或Facebook 使用 会话来认证用户? 就OOP而言,这是错误的吗?我在哪里想念这个概念? 问题答案: 该 使用 关系意味着

  • 因为聚合和组成是相关的关联,或者我们可以说它给出了对对象或其他任何东西之间关系的理解。 我发布这个问题是因为我在采访中问了一个问题,什么是组成和聚合。 所以根据我的理解,我给出了我的想法,如下所示。 http://www.coderanch.com/t/522414/java/java/Association-Aggregation-Composition 聚集、关联和组合 Java中的关联、聚合

  • 问题内容: 我想知道如何在python中以 UML术语 实现组合和聚合。 如果我了解: 聚合: class B: pass class A(object): def init(self): self.B = B 组成: 在其他语言中,我将其实现为指向B的指针。我猜这是python中的指针。 这样对吗? 问题答案: 如果我正确理解,聚合与组合是关于对象对其成员的职责(例如,如果删除实例,是否还要删除

  • 请考虑以下情况: 我如何在类图上表示< code>A和< code>B之间的关系?如果< code>B只保存一个< code>A(而不是一个数组),我会使用组合/聚合,但是在这种情况下,我不确定应该做什么。非常感谢你的帮助!

  • 统计 BuguDao提供如下常用的统计功能,它们都是基于Aggregation实现的。 /* 求最大值 */ public double max(String key) public double max(String key, BuguQuery query) /* 求最小值 */ public double min(String key) public double min(Stri

  • 按组合并返回结果 1,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。 相关代码可以参考 dubbo 项目中的示例 配置 搜索所有分组 <dubbo:reference interface="com.xxx.MenuService" group="*" merger="true" /> 合并指定分组