【问题标题】:OOP Inheritance面向对象继承
【发布时间】:2012-02-14 14:56:56
【问题描述】:

另一个开发人员和我正在建立一个网站,我们实现了我们自己的 OOP 模型,我们对此进行了很多讨论,但似乎我遇到了障碍。 请多多包涵

我们所有的类都扩展了Object,它有一个构造函数,它使用get_called_class()来获取类,然后get_class_vars()等加载列名,这意味着我们可以有一个savedelete,@ 987654324@、getAll等几个方法默认在一个类中,省去了很多代码。这很好。现在,我有一个类 InboundData,它有 3 个类从自身扩展,称为 VisitEnquiryBrochureRequest,它们有一个“inbound_data_id”,然后 InboundData 有一个看起来像这样的重载构造函数:

function __construct($id = '')
{   
    $this->className = get_called_class();
    $this->id = (int)$id;
    $this->tableName = strtolower($this->className);
    $this->setDbFields();
    $this->loadData();

    $this->contact = new Contact($this->contact_id);
    $this->address = new Address($this->address_id);
    $this->domain = new Domain($this->domain_id);
    $this->park = new Park($this->park_id);
}

问题是,contactaddressdomainpark 都受到保护,以阻止 Object 的方法将它们作为列名/类变量。这是我们对所有非 db 成员采用的方法,例如:

protected $contact;
protected $address;
protected $domain;
protected $park;

我们没有遇到什么问题,直到写前端代码才发现我明显不能填写$formObj->contact->var等,更何况我还没有写任何入站数据扩展的保存代码对象,这将需要保存所有附加的表。

请 OOP 专家告诉我们哪里出了问题,以及完成此任务的最佳方法是什么。随意提出任何问题,我知道这听起来一定很混乱。

【问题讨论】:

  • 你试过写getter吗? function get($field) { return $this->$field; } 并使用get("contact") 提取联系人
  • 顺便说一句,考虑到 PHP 5 中 __CLASS__ 魔术常数的行为,get_called_class 是多余的
  • @rdlowrey 谢谢,将来会使用,Eugen 这就是我现在使用的东西,但它无助于节省:( 这个扩展业务把我搞砸了。:/
  • 还要记住松耦合的方面。例如,更改 Address 类也可能会破坏 inboundData。 $this->address = new Address($this->address_id);

标签: php oop inheritance


【解决方案1】:

我不确定我是否理解你想要做什么,但听起来你有一个显示页面的某种 Template 对象,并且你想要获得 Enquiry(例如) contact 值并将其应用于模板。我建议这样做:

class TemplateBuilder {
    public static function addDataToTemplate(Template $tpl, Object $enq) {
       $enq->addToTemplate($tpl);
    }
}

这不是完全必要的,但下一步是:

class Enquiry extends Object {
   ...
   public function addToTemplate(Template $tpl) {
      $tpl->contact->var = $this->contact;
   }
}

这可以像您希望的那样保护仅Enquiry 的数据,并且您可以非常具体地控制要添加到哪些对象的数据。

这有点离题了,但我建议不要使用扩展程序并经历所有这些魔法。如果您有很多扩展 Object 的类可以使用的实用方法,您可以使用 Object(或任何其名称)作为成员来构造它们,并通过组合使用它。

【讨论】:

    【解决方案2】:

    一般来说,从 Object 扩展一切并不是一个好主意。它在您的模型中添加了许多并不真正属于的方法。它还打破了您通常期望从一个好的对象模型中获得的基本 is-a 关系。

    在不考虑前端的情况下构建后端也不是一个好主意。这会导致白费。

    就设置属性而言。你不能简单地添加 getter/setter 来访问你需要的东西吗?您是否考虑过使用 __get() 和 __set() 魔术方法?

    跟踪需要保存的修改的常用方法是使用 isDirty 标志。下一个问题是跟踪您从数据库加载的对象。这通常通过使用实体管理器来解决。

    如果您在无法解析的对象上设置属性时遇到问题,您也可以使用反射 API 来强制设置某些属性。 ReflectionProperty::setAccessible() 可以让你在私有/受保护的属性上设置一个值。

    【讨论】:

    • 这很好用。谢谢,除了,当尝试保存当前正在从访问中保存()的入站数据对象时,然后在重载的保存()中调用 parent::save();不知何故不仅从入站数据返回变量,而且从访问返回变量?所有这些都在使用来自 Object 的 get_class_vars。
    猜你喜欢
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多