Add a new review from a given reviewer to a given product.

        Args:
          reviewer: an instance of Reviewer.
          product: an instance of Product.
          review: a float value.
          date: date the review issued.

        Returns:
          the added new review object.

        Raises:
          TypeError: when given reviewer and product aren't instance of
            specified reviewer and product class when this graph is constructed.

def add_review(self, reviewer, product, review, date=None):
        """Add a new review from a given reviewer to a given product.

        Args:
          reviewer: an instance of Reviewer.
          product: an instance of Product.
          review: a float value.
          date: date the review issued.

        Returns:
          the added new review object.

        Raises:
          TypeError: when given reviewer and product aren't instance of
            specified reviewer and product class when this graph is constructed.
        """
        if not isinstance(reviewer, self._reviewer_cls):
            raise TypeError(
                "Type of given reviewer isn't acceptable:", reviewer,
                ", expected:", self._reviewer_cls)
        elif not isinstance(product, self._product_cls):
            raise TypeError(
                "Type of given product isn't acceptable:", product,
                ", expected:", self._product_cls)
        r = self._review_cls(review, date=date)
        self.graph.add_edge(reviewer, product, review=r)
        return r