Prototype Examples:

Java
Java
C#
C#
PHP
PHP
Python
Python
TypeScript
TypeScript
▸ Prototype Quick Review

Online Car Ordering in PHP

Car shopping these days has never been easier; if you're looking for a new car, the manufacturer website will usually feature a customization app on their website that will allow you to see what cool things you can equip your car with out of the box. While you can go into a website and customize what you'd like from scratch, they'll usually provide a few starter packages to make your experience a little smoother. This is something we can capture in our code using the Prototype Pattern!

The CarPackage and SportsCar:

interface CarPackage
{
   public function Clone(): CarPackage;
}

// Car implementation:
class SportsCarPackage implements CarPackage
{
   public $seatType;
   public $engineModel;
   public $hasSunRoof;

   public function __construct()
   {
       $this->seatType = "Basic";
       $this->engineModel = "V6";
       $this->hasSunRoof = false;
   }

   // Return a copy of the package:
   public function Clone(): CarPackage
   {
       $copy = new SportsCarPackage();
       $copy->seatType = $this->seatType;
       $copy->engineModel = $this->engineModel;
       $copy->hasSunRoof = $this->hasSunRoof;

       return $copy;
   }
}

Car Catalogue:

class CarCatalogue
{
   private $catalogue;

   public function __construct()
   {
       $this->catalogue = array();
   }

   public function Add(string $key, CarPackage $prototype)
   {
       $this->catalogue[$key] = $prototype->Clone();
   }

   public function Get(string $key): CarPackage
   {
       return $this->catalogue[$key]->Clone();
   }
}

Demo:

$catalogue = new CarCatalogue();

// Basic package with the default values:
$basicPackage = new SportsCarPackage();

$catalogue->Add("Basic", $basicPackage);

// Add a sportier option:
$trackPackage = new SportsCarPackage();

$trackPackage->seatType = "Leather";
$trackPackage->hasSunRoof = true;
$trackPackage->engineModel = "V6 Plus";

$catalogue->Add("Track", $trackPackage);

// Add the highest option:
$sportPackage = new SportsCarPackage();

$sportPackage->seatType = "Leather";
$sportPackage->hasSunRoof = true;
$sportPackage->engineModel = "V8";

$catalogue->Add("Sport", $sportPackage);

// Get a prototype package and put a more powerful engine in it!
$mySelectionPackage = $catalogue->Get("Sport");

$mySelectionPackage->engineModel = "V8 Hemi";

Find any bugs in the code? let us know!