Can i define an object inside a Class constructor?

The clean code says, that is not recommended to initialize objects, use if statement or other things in the __constructor. I have a class in which I used elements in the constructor which are not allowed. How to rebuild it to conform to the rules?

I searched on google! But I do not really understand and I hope that I will succeed in understanding with this particular example. The full code is also available on github: https://github.com/KoreLewi/21-blackjack-game

public function __construct(array $Cards = array())
    {
        if (empty($Cards)) {
            $Cards = $this->initEnglishDeck();
        }
        parent::__construct($Cards);
    }


    public function initEnglishDeck()
    {
        $arrCards = array();

        foreach ($this->suits as $suit) {
            foreach ($this->cards as $card) {
                $arrCards[] = new Card($suit, $card);
            }
        }
        return $arrCards;
    }

The full code is also available on github: https://github.com/KoreLewi/21-blackjack-game

Upvotes: 0

Views: 59

Answers (2)

Mark
Mark

Reputation: 1872

You could:

Move the if statement into the initEnglishDeck() function.

public function __construct(array $Cards = array()) {

    $Cards = $this->initEnglishDeck($Cards);
    parent::__construct($Cards);

}

public function initEnglishDeck($cards = array()) {

    if(!empty($cards)) return $cards;

    $arrCards = array();

    foreach ($this->suits as $suit) {

        foreach ($this->cards as $card) {

            $arrCards[] = new Card($suit, $card);

        }

    }

    return $arrCards;

}

Upvotes: 1

Girgias
Girgias

Reputation: 413

The pattern is Dependency Injection rather than initialising your dependencies internaly.

One way to "fix" your code is to have a CardDeck Interface and multiple (or just in this case) a EnglishDeck class which implements CardDeck. And in all the classes which require a card deck you inject it in the constructor like this:

class Game {
    /**
     * @var CardDeck
     */
    private $cardDeck

   public function __construct(CardDeck $cardDeck) {
       $this->cardDeck = $cardDeck
   }
}

In that case your Game class would still work even if you decide it to pass him another type of CardDeck, e.g. FrenchDeck which would also implement the CardDeck interface.

Upvotes: 3

Related Questions