【问题标题】:Dependencies inside an object对象内部的依赖关系
【发布时间】:2011-09-14 20:05:38
【问题描述】:

我有这个代码

鸭类{ 受保护的 $strVocabulary; 公共功能学习(){ $this->strVocabulary = '嘎嘎'; } 公共功能嘎嘎(){ 回声 $this->strVocabulary; } }

代码在 PHP 中,但问题不依赖于 PHP。 在它知道嘎嘎之前,鸭子必须学习。

我的问题是:如何仅在调用 Learn() 后才使 Quack() 可调用?

【问题讨论】:

  • 不确定我是否理解这个问题。如果您是这样想的话,这两个功能并不相互依赖。它们都修改了$strVocabulary,但它们并不相互依赖。
  • @Jonathan 从功能的角度来看,它们是分开工作的,但从逻辑的角度来看,您首先必须调用 learn 然后 quack 才能获得一些有效的结果。
  • 您的问题也是如此,“如何在调用 Learn 后使 Quack 可调用?”还是您只是说这是您的结构,您将在代码中管理方法调用的顺序?
  • @Jonathan - 是的(“如何仅在调用 Learn 后才使 Quack 可调用”)。我也在考虑设计模式,以及这种情况是否与其中一种相关。

标签: oop design-patterns


【解决方案1】:

不,这不违反任何 OOP 原则。

一个突出的例子是一个对象的行为取决于是否建立了连接(例如函数doNetworkStuff()取决于openConnection())。

在 Java 中,甚至还有一个 typestate checker,它在编译时执行此类检查(Duck 是否已经 Quack())。我经常有这样的依赖关系作为接口的前提条件,并使用一个转发类,其唯一目的是协议和检查它转发到的对象的状态,即协议哪些函数已在对象上调用,并在何时抛出异常(例如 InvalidStateException)不满足前提条件。

处理此问题的设计模式是state:它允许对象在其内部状态发生变化时改变其行为。该对象将出现更改其类。 design pattern book from the Gang of Four 也使用了上述网络连接的示例,无论是否建立。

【讨论】:

    【解决方案2】:

    如果你想修正顺序,那么你可以使用一个抽象基类,在函数 quack() 中,你首先调用 learn(),然后调用抽象方法 doquack()(其他好名字,这必须是由每个派生类实现)。

    【讨论】:

    • 如果对象可以独立控制其状态,这是一个很好的解决方案。如果客户端或环境控制状态,它就不起作用。
    • 我同意。在那种情况下,我会选择 state。
    【解决方案3】:

    我的问题是:我如何让 Quack() 只有在 Learn() 之后才能调用 被召唤了?

    您可以分离关注点:

    class EnrolleeDuck {
      public function Learn() {
       return new AlumnusDuck('quack');
      }
    }
    
    class AlumnusDuck
    {
      protected $strVocabulary;
    
      public function __construct(&strVocabulary) {
        &this->strVocabulary = &strVocabulary;
      }
    
      public function Quack() {
       echo $this->strVocabulary;
      }
    }
    

    这是我在 PHP 中的第一行,请随时更正

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      相关资源
      最近更新 更多