PHP design Pattern Instance Learning notes

Source: Internet
Author: User
Tags abstract foreach

One, Value object mode

Again, before the design pattern-the value object pattern-you have to understand value passing and reference passing:


1. Value Object Pattern Concept:
If you assign the same object resource to two different variables and then change one of the variables, the other variable remains unaffected. This is the purpose of using the value object pattern.
Look at the following example:

The code is as follows Copy Code
<?php

Class Baddollar {
protected $amount;

Public function __construct ($amount =0) {
$this->amount = (float) $amount;
}

Public Function Getamount () {
return $this->amount;
}

Public function Add ($dollar) {
$this->amount + + $dollar->getamount ();
}
}

Class Work {
protected $salary;

Public Function __construct () {
$this->salary = new Baddollar (200);
}

Public Function PayDay () {
return $this->salary;
}

}

Class Person {
Public $wallet;
}


$job = new Work;
$p 1 = new person;
$p 2 = new person;
$p 1->wallet = $job->payday ();
Print_r ($p 1->wallet->getamount ()); 200

$p 2->wallet = $job->payday ();
Print_r ($p 2->wallet->getamount ()); 200

$p 1->wallet->add ($job->payday ());
Print_r ($p 1->wallet->getamount ()); 400

This is bad-actually 400
Print_r ($p 2->wallet->getamount ()); 400

This is really bad-actually 400
Print_r ($job->payday ()->getamount ()); 400


Looking at the above example, you can see that the obvious error is that $P1 and $P2 are using the same Baddollar object, first, the class work and instances of the class person have been created. So, assuming that each employee initially has an empty electronic wallet, the employee's electronic wallet Person:wallet is assigned to the object resource variable returned by the work::p Ayday () function, so it is set as an object instance of a Baddollar class. In fact, $job:: Salary, $p 1::wallet and $p2::wallet Point to an instance of the same object.
Using the value object pattern, redesign the dollar object as follows

The code is as follows Copy Code

Class Dollar {
protected $amount;

Public function __construct ($amount =0) {
$this->amount = (float) $amount;
}

Public Function Getamount () {
return $this->amount;
}

Public function Add ($dollar) {
return new Dollar ($this->amount + $dollar->getamount ());
}
}

As you can see, the main change is in the Dollar:add () function, which is to create and return a new dollar instance, so although you specify the current object to multiple variables, the change of each variable does not affect the other variable instances.
Value object Pattern Design Note:

1. Protect the properties of the value object and prohibit direct access.

2. Assign values to properties in the constructor.

3. Remove any method function (setter) that changes the value of the property, otherwise the property value can easily be changed

Second, the Strategy model

1. Strategy Model Concept
the policy pattern encapsulates each algorithm into a separate class with a common interface for a set of algorithms, which allows the algorithm to change independently from the client using the algorithm. so that the program structure more flexible, with better scalability and maintenance
2. Strategy Pattern Structure Chart



3. Policy Mode role Description
abstract Policy (strategy) role: A public interface that defines all supported algorithms. is usually implemented as an interface or an abstraction. The context uses this interface to invoke its concretestrategy-defined algorithm.
specific policy (concretestrategy) role: implement a specific algorithm with strategy interface
Environment (context) role: holds a reference to a strategy class and uses a Concretestrategy object to configure
4. Example of a policy pattern
For example, the shopping cart system, when calculating the total price for the goods, the average member must be the price of the commodity multiplied by the number, but for the intermediate member to provide 8 discount, to the senior member to provide 70 percent discount, this scenario can be implemented using the policy model:

The code is as follows Copy Code

<?php

Abstract policy role "for interface or abstract class, for specific policy class inheritance"
Interface Strategy
{
Public Function Computeprice ($price);
}

Specific policy roles-general membership policy classes
Class Genernalmember implements Strategy
{
Public Function Computeprice ($price)
{
return $price;
}
}

Specific policy role-intermediate member policy class
Class Middlemember implements Strategy
{
Public Function Computeprice ($price)
{
return $price * 0.8;
}
}

Specific policy roles-advanced membership policy classes
Class Hignmember implements Strategy
{
Public Function Computeprice ($price)
{
return $price * 0.7;
}
}

Environment role Implementation Class
Class Price
{
Specific policy objects
Private $strategyInstance;

Constructors
Public function __construct ($instance)
{
$this->strategyinstance = $instance;
}

Public function compute ($price)
{
return $this->strategyinstance->computeprice ($price);
}
}

Client use
$p = new Price (new Hignmember ());

$totalPrice = $p->compute (100);

Echo $totalPrice; 70


Three, Command mode

1. Command mode concept:
Pass a request from the client to an object so that you can parameterize the customer with different requests. The decoupling of the behavior requester and the behavior performer enables loose coupling between the two to accommodate the change.
2. Participants:

    • Command: Defines an abstraction above a method call;
    • Concretecommand (Specific command): an operation of the implementation;
    • Invoker (caller): Refers to the command instance as an action available to it.

The code is as follows Copy Code
<?php
Command
Interface Validator
{
/**
* The method could have any parameters.
* @param mixed
* @return Boolean
*/
Public Function IsValid ($value);
}

Specific orders
Class Morethanzerovalidator implements Validator
{
Public Function IsValid ($value)
{
return $value > 0;
}
}

Specific orders
Class Evenvalidator implements Validator
{
Public Function IsValid ($value)
{
return $value% 2 = 0;
}
}

By the caller
Class Arrayprocessor
{
protected $_rule;

Public function __construct (Validator $rule)
{
$this->_rule = $rule;
}

Public function process (array $numbers)
{
foreach ($numbers as $n) {
if ($this->_rule->isvalid ($n)) {
echo $n, "";
}
}
}
}

Client
$processor = new Arrayprocessor (new Evenvalidator ());
$processor->process (Array (1, 20, 18, 5, 0, 31, 42));

In this pattern, the invoker (caller) knows that the command passed to it does not have to rely on the real Concretecommand (specific command) implementation, resolving problems related to method invocation through configuration, such as UI control buttons and menus, and so on, referencing a command, Their behavior is presented through a common Concretecommand instance.

IV. Observer model

First understand the concept of the Observer pattern : An object makes itself observable by adding a method that allows another object, the observer, to register itself. When an observable object changes, it sends the message to the registered observer. The actions that these observers perform with this information are independent of the observable objects. The result is that objects can talk to each other without having to understand why. The Observer pattern is an event system, meaning that the pattern allows a class to observe the state of another class, and when the observed class state changes, the observation class can receive notification and make the corresponding action; The Observer pattern provides you with the avoidance of tight coupling between components. Look at the example below and you'll see!
1. Implement message push using observer mode

The code is as follows Copy Code

<?php

Observer
Interface IObserver
{
Public function notify ();
}

Define object interfaces that can be observed
Interface IObservable
{
Public Function Addobserver ($observer);
}

Implement IObservable interface
Class Messagesystem Implements iobservable
{
Private $_observers = Array ();

Public Function Addobserver ($observer)
{
$this->_observers = $observer;
}

Public Function donotify ()
{
foreach ($this->_observers as $o)
{
$o->notify ();
}
}
}

Implement IObserver interface
Class User Implements IObserver
{
Public function __construct ($username)
{
echo "I am the new user {$username}<br/>";
}
Notify the Observer method
Public Function Notify ()
{
Echo ' welcome new user ';
}
}

Use
$u = new Messagesystem ();

$u->addobserver (New User (' xiaoming '));
$u->addobserver (New User (' Little Red '));
$u->addobserver (New User (' Little Black '));

$u->donotify ();


2. A good example from Phpchina:


/**
* Define the Observation interface
*/
Interface Subject
{
Public Function Attach ($Observer); Add Observer
Public Function Detach ($Observer); Kick out The Observer
Public function Notify (); Notify observers when conditions are met
Public Function subjectstate ($Subject); Observation conditions
}

/**
* The specific implementation of the observation class
*/
Class Boss Implements Subject
{
Public $_action;

Private $_observer;

Public Function Attach ($Observer)
{
$this->_observer[] = $Observer;
}

Public Function Detach ($Observer)
{
$ObserverKey = Array_search ($Observer, $this->_observer);

if ($ObserverKey!== false)
{
unset ($this->_observer[$ObserverKey]);
}
}

Public Function Notify ()
{
foreach ($this->_observer as $value)
{
$value->update ();
}
}

Public Function subjectstate ($Subject)
{
$this->_action = $Subject;
}
}

/**
* Abstract Observer
*
*/
Abstract class Observer
{
protected $_username;

protected $_sub;

Public function __construct ($Name, $Sub)
{
$this->_username = $Name;
$this->_sub = $Sub;
}

public abstract function Update (); Receive through method
}

/**
* Observer
*/
Class Stockobserver extends Observer
{
Public function __construct ($name, $sub)
{
Parent::__construct ($name, $sub);
}

Public Function Update ()
{
echo $this->_sub->_action $this->_username. "You run quickly ...";
}
}

$huhansan = new Boss (); The person being observed

$gongshil = new Stockobserver ("Sanmao", $huhansan); Initialize Observer

$huhansan->attach ($gongshil); Add an Observer
$huhansan->attach ($gongshil); Add an observer of the same
$huhansan->detach ($gongshil); Kick out an observer in the base

$huhansan->subjectstate ("The police came"); Meet the conditions of the meeting

$huhansan->notify (); Through all the effective observers

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.