johnlemon
johnlemon

Reputation: 21449

Dependencies inside an object

I have this code

class Duck {
  protected $strVocabulary;
  public function Learn() {
   $this->strVocabulary = 'quack';
  }

  public function Quack() {
   echo $this->strVocabulary;
  }
}

The code is in PHP but the question is not PHP dependent. Before it knows to Quack a duck has to Learn.

My question is: How do I make Quack() invokable only after Learn() has been called?

Upvotes: 7

Views: 126

Answers (3)

Andriy Tylychko
Andriy Tylychko

Reputation: 16266

My question is: How do I make Quack() invokable only after Learn() has been called?

you can separate concerns:

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;
  }
}

It's my first lines in PHP, feel free to correct

Upvotes: 0

DaveFar
DaveFar

Reputation: 7447

No, that does not violate any OOP principle.

A prominent example is an object who's behavior depends on whether a connection is established or not (e.g. function doNetworkStuff() depends on openConnection()).

In Java, there is even a typestate checker, which performs such checks (whether Duck can already Quack()) at compile time. I often have such dependencies as preconditions for interfaces, and use a forwarding class whose sole purpose is protocolling and checking the state of the object it forwards to, i.e. protocol which functions have been called on the object, and throw exceptions (e.g. InvalidStateException) when the preconditions are not met.

A design pattern that handles this is state: It allows an object to alter its behavior when its internal state changes. The object will appear to change its class. The design pattern book from the Gang of Four also uses the example above of a network connection either being established or not.

Upvotes: 3

AD.Net
AD.Net

Reputation: 13399

If you want to fix the order then you can use an abstract base class where in the function quack() you call learn() first and then abstract method doquack() (some other good name, and this will have to be implemented by each derived class).

Upvotes: 1

Related Questions