Avatar of rgb192
rgb192
Flag for United States of America asked on

creating an instance of a class inside a class

followup question to:

https://www.experts-exchange.com/questions/28423145/calling-the-parent-instead-of-child-class.html?anchorAnswerId=40052859#a40052859



getInstance method returns an object. The important thing is that it can return different types of object based on the extension of the file name given


can you give examples of an instance of a class created in the class
most tutorials teach objects outside class
PHP

Avatar of undefined
Last Comment
rgb192

8/22/2022 - Mon
Ray Paseur

This is generally what is referred to as the Factory Pattern.
http://en.wikipedia.org/wiki/Factory_method_pattern
http://www.phptherightway.com/pages/Design-Patterns.html (Very Good Site, BTW)
http://coderoncode.com/2014/01/19/design-patterns-php-factories.html (Have not read it all, but it looks good)
rgb192

ASKER
<?php
class ShopProduct {
    private $title;
    private $producerMainName;
    private $producerFirstName;
    protected $price;
    private $discount = 0; 
    private $id = 0;
    
    public function __construct(   $title, $firstName, 
                            $mainName, $price ) { 
        $this->title             = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName  = $mainName;
        $this->price             = $price;
    }

    public function setID( $id ) {
        $this->id = $id;
    }

    public function getProducerFirstName() {
        return $this->producerFirstName;
    }

    public function getProducerMainName() {
        return $this->producerMainName;
    }

    public function setDiscount( $num ) {
        $this->discount=$num;
    }

    public function getDiscount() {
        return $this->discount;
    }
    
    public function getTitle() {
        return $this->title;
    }

    public function getPrice() {
        return ($this->price - $this->discount);
    }

    public function getProducer() {
        return "{$this->producerFirstName}".
               " {$this->producerMainName}";
    }

    function getSummaryLine() {
        $base  = "Item: $this->title ( $this->producerMainName, ";
        $base .= "$this->producerFirstName )"; 
        return $base;
    }

    public static function getInstance( $id, PDO $pdo ) {
        $query = "select * from products where id='$id'";
        $stmt = $pdo->prepare("select * from products where id=?");
        $result = $stmt->execute( array( $id ) );
        $row = $stmt->fetch( );
        if ( empty( $row ) ) { return null; }

        if ( $row['type'] == "book" ) {
            $product = new BookProduct( 
                                    $row['title'], 
                                    $row['firstname'], $row['mainname'], 
                                    $row['price'], $row['numpages'] ); 
        } else if ( $row['type'] == "cd" ) {
            $product = new CdProduct(
                                    $row['title'], 
                                    $row['firstname'], $row['mainname'], 
                                    $row['price'], $row['playlength'] ); 
        } else {
            $product = new ShopProduct(     
                                    $row['title'], 
                                    $row['firstname'], $row['mainname'], 
                                    $row['price'] ); 
        }
        $product->setId(            $row['id'] );
        $product->setDiscount(      $row['discount'] );
        return $product;
    }
}

class CdProduct extends ShopProduct {
    private $playLength = 0;

    public function __construct(   $title, $firstName, 
                            $mainName, $price, $playLength ) { 
        parent::__construct(    $title, $firstName, 
                                $mainName, $price );
        $this->playLength = $playLength;
    }

    public function getPlayLength() {
        return $this->playLength;
    }

    function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": playing time - $this->playLength";
        return $base;
    }
 
}

class BookProduct extends ShopProduct {
    private $numPages = 0;

    public function __construct(   $title, $firstName, 
                            $mainName, $price, $numPages ) { 
        parent::__construct(    $title, $firstName, 
                                $mainName, $price );
        $this->numPages = $numPages;
    }

    public function getNumberOfPages() {
        return $this->numPages;
    }
   
    function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": page count - $this->numPages";
        return $base;
    }

    public function getPrice() {
        return $this->price;
    }
}

require_once("generate_product_pdo.php");
$pdo = getPDO();
$obj = ShopProduct::getInstance( 1, $pdo );
print_r( $obj );
$obj = ShopProduct::getInstance( 2, $pdo );
print_r( $obj );
$obj = ShopProduct::getInstance( 3, $pdo );
print_r( $obj );
?>

Open in new window


is this factory pattern because line64-79 creates (is creates the same as returns???) a new object based upon column in a row $row['type']
Member_2_248744

hello, to your "is this factory pattern because line64-79 creates", the short answer is "YES", , but in programming and certainly PHP code work, there really is not just ONE way to have or use a "Factory" Class object, that Changes the functioning of your Class object according to an input or database SELECT. many times the Class object will change in small ways from inputs, and most will not say that's a Factory change, and sometimes there can be Large Changes in object functioning from inputs or DB SELECT, and some may NOT call is a Factory change, and others may say that it IS a Factory change, it sometime depends on the degree of change, but if you have a DIFFERENT object class produced as your example -
      $product = new BookProduct()
      $product = new CdProduct()
      $product = new ShopProduct()

then that would by most be called a "factory pattern", but trying to name a pattern, may not be much help to a code writer, if he does not understand how and why to write adaptable (changing) code that can adjust to different web pages and code inputs, this is the reason that a "Factory" Class is used, to prevent writing code for 3 different Classes, and write One Class that can adapt and change to three different functioning from an input.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
rgb192

ASKER
i do not understand how this is a factory pattern:
      $product = new BookProduct()
      $product = new CdProduct()
      $product = new ShopProduct()
Ray Paseur

i do not understand how this is a factory pattern:
      $product = new BookProduct()
      $product = new CdProduct()
      $product = new ShopProduct()
I think that's kind of the opposite of a Factory pattern.  Please see the explanation given here.  Now that I have read it all, I think it's a great example showing how and when to use Factory.
SOLUTION
Member_2_248744

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ASKER CERTIFIED SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
rgb192

ASKER
"We can define a factory as a simple design pattern that give us a convenient way to instantiate objects. A factory is capable of creating different types of objects without necessarily knowing what type of object is actually being created."

Do you have an Idea or understanding of writing a Class code that can be adaptable (maybe a factory) and change from the web page inputs, to be a way to make better code?

For the sake of argument, let's imagine that every single product has its own unique class. So we would have something like this:  (many classes)


thanks for factory infomation
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.