Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OOP - without GET / SET

Tags:

oop

php

Following the "Tell, don't Ask"-principle one should not use getters in OOP.

But how to solve problems where (at least I think so) one actually need some "inside information" from an object? So how to change the following example so that the create_bill() function does not need to ASK for the price for each item?

class chopping_cart {

    private $itemlist = array();

    function item_add( $name, $price ) {
        $his->itemlist[]=new item( $name, $price );
    }
    private create_bill() {

        foreach $this->itemlist AS $element;
        $sum += $element->get_price();

    }
}


class item {
    private $name;
    private $price;
    function __construcor($name,$price) {...}
    function get_price() {
        return $price;
    }
}

Usage:

$sc = new shopping_cart()
$sc->item_add( "Bike", 1.00 );
$sc->item_add( "Ship", 2.00 );
$sc->create_bill();
like image 449
Tom Avatar asked Apr 30 '12 22:04

Tom


2 Answers

If you're not using the requested data/state to change the object you're referring to, I don't think there's anything wrong with using getters at all.

The principle talks about a scenario like this:

if ($item->get_price() < 5) {
    $item->set_price(5);
}

That should be turned into something like $item->set_minimum_price(5).

like image 62
Ja͢ck Avatar answered Nov 09 '22 18:11

Ja͢ck


There are two items from the "Tell, Don't Ask" article you're referring to that bear close examination:

  1. [...] do not ask [objects] questions about their state, make a decision, and then tell them what to do.
    With your particular example, chopping_cart only queries the objects & makes a decision. Crucially, it doesn't go on to tell them what to do.
  2. According to Design by Contract, as long as your methods (queries and commands ) can be freely intermixed, and there is no way to violate the class invariant by doing so, then you are ok. But while you are maintaining the class invariant, you may have also dramatically increased the coupling between the caller and the callee depending on how much state you have exposed.
    Getter calls can generally be freely intermixed, so there's no coupling caused by the need to maintain class invariants.

Thus, getters don't cause the issues that the "tell, don't ask" principle is supposed to prevent.

like image 22
outis Avatar answered Nov 09 '22 17:11

outis