There are numerous ways to structure the code and project for your web application, and you can put as much or as little thought as you like into architecture. But it is usually a good idea to follow common patterns because it will make your code easier to manage and easier for others to understand
Singleton Pattern
We use the singleton pattern in order to restrict the number of instances that can be created from a resource consuming class to only one.Singleton Pattern
class Singleton {
// Hold the class instance.
private static $instance = null;
// The constructor is private
// to prevent initiation with outer code.
private function __construct()
{
// The expensive process (e.g.,db connection) goes here.
}
// The object is created from within the class itself
// only if the class has no instance.
public static function getInstance()
{
if (self::$instance == null)
{
self::$instance = new Singleton();
}
return self::$instance;
}
}
Since we restrict the number of objects that can be created from a class to only one, we end up with all the variables pointing to the same, single object
// All the variables point to the same object.
$object1 = Singleton::getInstance();
$object2 = Singleton::getInstance();
$object3 = Singleton::getInstance();
Factory Pattern :
We should consider the use of the factory design pattern in those cases where we need to free a class from making the objects that it manages. For this aim, we make the objects in a dedicated factory class. When we use the factory pattern, we separate the making of objects into a dedicated class whose main responsibility is the making of objects.
Create Interface :
Strategy Pattern:
We should consider the use of the strategy design pattern in those cases where we want to choose which object to create from several similar classes during the runtime of the program. The classes are similar in that they can use the same name for their methods, but they are different in the way that they apply the methods. Therefore, the strategy pattern uses an interface that the classes can implement Here are two class bmwCouponGenerator and mercedesCouponGenerator both have same method name addStockDiscount Create interface
We should consider the use of the factory design pattern in those cases where we need to free a class from making the objects that it manages. For this aim, we make the objects in a dedicated factory class. When we use the factory pattern, we separate the making of objects into a dedicated class whose main responsibility is the making of objects.
Create Interface :
interface Car {
function getModel();
function getWheel();
}
Create Class CarModelS
class CarModelS implements Car {
protected $model = 's';
protected $wheel = 'sports';
protected $sunRoof = true;
public function getModel()
{
return $this->model;
}
public function getWheel()
{
return $this->wheel;
}
}
Create Class CarModelR
class CarModelR implements Car {
protected $model = 'r';
protected $wheel = 'regular';
protected $sunRoof = false;
public function getModel()
{
return $this->model;
}
public function getWheel()
{
return $this->wheel;
}
}
Create Factory Class
class CarFactory {
protected $car;
// Determine which model to manufacture, and instantiate
// the concrete classes that make each model.
public function make($model=null)
{
if(strtolower($model) == 'r')
return $this->car = new CarModelR();
return $this->car = new CarModelS();
}
}
Create Order Class
class CarOrder {
protected $carOrders = array();
protected $car;
// First, create the carFactory object in the constructor.
public function __construct()
{
$this->car = new CarFactory();
}
public function order($model=null)
{
// Use the make() method from the carFactory.
$car = $this->car->make($model);
$this->carOrders[]=$car->getModel();
}
public function getCarOrders()
{
return $this->carOrders;
}
}
Testing :
$carOrder = new CarOrder
$carOrder->order('r');
var_dump($carOrder->getCarOrders());
Strategy Pattern:
We should consider the use of the strategy design pattern in those cases where we want to choose which object to create from several similar classes during the runtime of the program. The classes are similar in that they can use the same name for their methods, but they are different in the way that they apply the methods. Therefore, the strategy pattern uses an interface that the classes can implement Here are two class bmwCouponGenerator and mercedesCouponGenerator both have same method name addStockDiscount Create interface
interface carCouponGenerator {
function addStockDiscount();
}
Create bmwCouponGenerator classclass bmwCouponGenerator implements carCouponGenerator {
private $discount = 0;
private $isHighSeason = false;
private $bigStock = true;
public function addStockDiscount()
{
if($this->bigStock) return $this->discount += 7;
return $this->discount +=0;
}
}
Create mercedesCouponGenerator classclass mercedesCouponGenerator implements carCouponGenerator {
private $discount = 0;
private $isHighSeason = false;
private $bigStock = true;
public function addStockDiscount()
{
if($this->bigStock) return $this->discount += 10;
return $this->discount +=0;
}
}
Apply strategy design patternclass couponGenerator {
private $carCoupon;
// Get only objects that belong to the interface.
public function __construct(carCouponGenerator $carCoupon)
{
$this->carCoupon = $carCoupon;
}
// Use the object's methods to generate the coupon.
public function getCoupon()
{
$discount = $this->carCoupon->addStockDiscount();
return $coupon = "Get {$discount}% off the price of your new car.";
}
}
Testing$car = "bmw";
$carObj = couponObjectGenerator($car);
$couponGenerator = new couponGenerator($carObj);
echo $couponGenerator->getCoupon();
echo "";
$car = "mercedes";
$carObj = couponObjectGenerator($car);
$couponGenerator = new couponGenerator($carObj);
echo $couponGenerator->getCoupon();
Adaptor Pattern:
Adapter pattern works as a bridge between two incompatible interfaces.
The adapter pattern is one of the simplest and most used patterns. We use it in those cases that we incorporate a new class that essentially performs the same task as an old class, but it has different names for the methods. The adapter pattern suggests that we solve the problem by using an adapter class. The methods of the adapter class, are constructed from the new class's methods as bodies wrapped with the names of the old class's methods. By doing so, the adapter translates the new interface to the old interface, and so saves us the trouble of re-writing our existing code. The original classAdapter pattern works as a bridge between two incompatible interfaces.
class Pay1 {
function addItem($itemName)
{
var_dump("1 item added: " . $itemName );
}
function addPrice($itemPrice)
{
var_dump("1 item added to total with the price of: " . $itemPrice );
}
}
The Customer class uses the Pay1 class in order to pay.class Customer {
private $pay;
function __construct($pay)
{
$this -> pay = $pay;
}
function buy($itemName, $itemPrice)
{
$this -> pay -> addItem($itemName);
$this -> pay -> addPrice($itemPrice);
}
}
Let's test the code by making the customer pay for a item$pay = new Pay1();
$customer = new Customer($pay);
$customer -> buy("item", 2);
Now New Class Added with name Pay2class Pay2 {
function addOneItem($name)
{
var_dump("1 item added: " . $name);
}
function addPriceToTotal($price)
{
var_dump("1 item added to total with the price of: " . $price);
}
// Unique method
addItemAndPrice($name,$price)
{
$this -> addOneItem($name);
$this -> addPriceToTotal($price);
}
}
$pay = new Pay2();
$customer = new Customer($pay);
$customer -> buy("lollipop", 2);
And the result is, not surprisingly, a fatal error: While the classes do essentially the same task, we cannot replace between the two classes because they have different names for their methods. The adapter pattern suggests that we solve the incompatibility problem by translating the new class interface to the old class interface. In order to translate the new interface to the old interface, the adapter pattern suggests writing an adapter class with the following two main features: The adapter class needs to implement the interface of the original class. The adapter class needs to hold a reference to the new class. old class needs to have an interface, but since it doesn't have an interface let's extract a PayItem interface from the Pay1 class. Like the Pay1 class, the interface will have the following two methods:interface PayItem {
function addItem($itemName);
function addPrice($itemPrice);
}
class Pay1 implements PayItem {
function addItem($itemName)
{
var_dump("1 item added: " . $itemName );
}
function addPrice($itemPrice)
{
var_dump("1 item added to total with the price of: " . $itemPrice );
}
}
Write the adapter classclass Pay2Pay1Adapter implements PayItem {}
class Pay2Pay1Adapter implements PayItem {
// The adapter holds a reference to the new class.
private $payObj;
// In order to hold a reference, we need to pass the new
// class's object throught the constructor.
function __construct($payObj)
{
$this -> payObj = $payObj;
}
// The name of the methods is that of the old class.
// The code within the methods uses the code of the new class.
function addItem($itemName)
{
$this -> payObj -> addOneItem($itemName);
}
}
$pay2 = new Pay2();
$pay = new Pay2Pay1Adapter($payKal);
$customer = new Customer($pay);
$customer -> buy("item", 2);
Comments
Post a Comment