Learning notes for simple factory patterns in PHP

Source: Internet
Author: User
Tags class definition extend getmessage inheritance

Simple Factory mode:

① abstract base class: class definition abstract Some methods to implement in subclasses
② inherits from the abstract base class: Implementing an abstract method in a base class
③ Factory class: Used to instantiate objects

What is the purpose or goal of using the factory model?

The biggest advantage of the factory pattern is that the object is created by encapsulating the process of creating the object so that a new object can be generated at any time.
Reduce the code to copy sticky paste, coupling relationship heavy, pull the other part of the code.

In layman's parlance, once you have created an object to use new, you now encapsulate the process.
Suppose you do not use Factory mode: So many places invoke Class A, and the code creates an instance like this: New A (), assuming that one day you need to modify the name of Class A, which means that many of the calling code will be modified.

The advantage of the factory pattern is on the creation object.


The advantage of the factory pattern is on the creation object. Creating a factory (a function or a class method) to create a new object, its task is to encapsulate the creation process of the object,
Creating objects is not in the form of new. Instead, you define a method to create an object instance.

Each class may need to connect to the database. Then encapsulate the connection database in a class. Later in other classes through the class name:

Why the introduction of abstract concepts?


Think about it, in real life, when we can not determine a specific thing, often put a class of things into abstract categories.
Factory Method:
For example, your factory is called "Cigarette factory", then there can be "seven Wolf Factory" "Chinese factory" and so on, but, this factory only plant a product: cigarettes;
Abstract Factory: Unable to describe what product it is producing, it produces many types of products (so the abstract factory will produce a child factory).
Your factory is a comprehensive, production of "a series of" products, not "one", such as: the production of "cigarettes", as well as "beer" and so on. Then it can also be derived from the specific factory, but these factories are the production of this series of products, but probably because of the different geographical, in order to adapt to local tastes, taste is not the same.
Factory Model: A factory that is understood to produce only one product. such as the production of cigarettes.
Factory Method: A product line of a factory. such as the keyboard generation process.

Others will retort: eat full of nothing to do, must modify the class name? This might. Generally do not modify the class name.

In fact, there are many variants of the factory model, grasping the essence is the key: As long as can be based on different parameters to generate different class instances, then the design of the factory model.

This reminds me that there are often methods in the framework that are responsible for generating specific class instances for invocation.

Read the article and look back at this picture, the effect will be better

Adopt Package method

<?php
Class calc{
/**
* Calculation results
*
* @param int|float $num 1
* @param int|float $num 2
* @param string $operator
* @return Int|float
*/
Public function Calculate ($num 1, $num 2, $operator) {
try {
$result = 0;
Switch ($operator) {
Case ' + ':
$result = $num 1+ $num 2;
Break
Case '-':
$result = $num 1-$num 2;
Break
Case ' * ':
$result = $num 1* $num 2;
Break
Case '/':
if ($num 2==0) {
throw new Exception ("divisor cannot be 0");
}
$result = $num 1/$num 2;
Break
}
return $result;
}catch (Exception $e) {
echo "You entered incorrectly:". $e->getmessage ();
}
}
}
$test =new Calc ();
echo $test->calculate (2,3, ' + ');//Print: 5
echo $test->calculate (5,0, '/');//print: You entered incorrectly: divisor cannot be 0
?>

Advantages: The above code uses the Object-oriented encapsulation feature, as long as the Include this class, other pages can be used casually

Disadvantages: Inability to extend and maintain flexibility

For example, to add a "remainder" operation, you need to include a branch statement in the switch statement block, and the code needs to make the following changes

<?php
Class calc{
Public function Calculate ($num 1, $num 2, $operator) {
try {
$result = 0;
Switch ($operator) {
//...... Omitted......
Case '% ':
$result = $num 1% $num 2;
Break
//...... Omitted......
}
}catch (Exception $e) {
echo "You entered incorrectly:". $e->getmessage ();
}
}
}
?>
Code Analysis: Using the above method to add a new functional operation to the calculator has the following disadvantages

① need to change the original code block, may be in order to "add new features" and change the original code, accidentally changed the original code wrong
② If you want to add a lot of functionality, for example: ' Power ', ' root ', ' log ', ' trigonometric ', ' statistics ', or add some programmer-specific computing functions, such as: and, or, not, Xor, so you need to add N branch statements in the switch statement. Imagine, a function of computing function if there are twenty or thirty case branch statements, the code will be more than one screen, not only the readability of the code is greatly reduced, the key is, in order to add small functionality, but also to allow the rest of the irrelevant to participate in the interpretation, which makes the implementation of the program efficiency

Solution: Using Oop's inheritance and polymorphic thinking

<?php
/**
* Operation class
* Class must be declared abstract because it contains abstract methods
*/
Abstract class operation{
An abstract method cannot contain a function body
Abstract public Function GetValue ($num 1, $num 2);//strongly require subclasses to implement this function
}
/**
* Addition class
*/
Class Operationadd extends Operation {
Public Function GetValue ($num 1, $num 2) {
return $num 1+ $num 2;
}
}
/**
* Subtraction Class
*/
Class Operationsub extends Operation {
Public Function GetValue ($num 1, $num 2) {
Return $num 1-$num 2;
}
}
/**
* Multiplication Class
*/
Class Operationmul extends Operation {
Public Function GetValue ($num 1, $num 2) {
return $num 1* $num 2;
}
}
/**
* Division Class
*/
Class Operationdiv extends Operation {
Public Function GetValue ($num 1, $num 2) {
try {
if ($num 2==0) {
throw new Exception ("divisor cannot be 0");
}else {
return $num 1/$num 2;
}
}catch (Exception $e) {
echo "error message:". $e->getmessage ();
}
}
}
?>

This takes an object-oriented inheritance feature, first declaring a virtual base class, and specifying the method that subclasses must implement in the base class (GetValue ())

Analysis: By adopting the Object-oriented inheritance feature, we can easily extend the original program, such as: ' Powers ', ' square ', ' logarithm ', ' trigonometric ', ' statistics ' and so on.

<?php
/**
* Remainder category (remainder)
*
*/
Class Operationrem extends Operation {
Public Function GetValue ($num 1, $num 2) {
return $num 1% $num 12;
}
}
?>

We only need to write a separate class (this class inherits the virtual base class), completes the corresponding function in the class (for example: the computation of the exponentiation), and greatly reduces the coupling degree, facilitates the future maintenance and the extension

There is still a problem unresolved, that is, how to get the program to instantiate the corresponding object based on the operator entered by the user?
Workaround: Use a separate class to implement the instantiation process, this class is the factory
The code is as follows:

<?php
/**
* Engineering class, mainly used to create objects
* Function: According to the input operation symbol, the factory can instantiate the appropriate object
*
*/
Class factory{
public static function Createobj ($operate) {
Switch ($operate) {
Case ' + ':
return new Operationadd ();
Break
Case '-':
return new Operationsub ();
Break
Case ' * ':
return new Operationsub ();
Break
Case '/':
return new Operationdiv ();
Break
}
}
}
$test =factory::createobj ('/');
$result = $test->getvalue (23,0);
echo $result;
?>

And then expand some

For example, depending on what the player has entered (although it can be converted to another string) to determine the class to be made, the player will not enter the code: New Marine ().
Like StarCraft, PHP does not have the ultimate class, and if the classes and interfaces are the units, then the design pattern is your tactics and control, which allows you to win with a variety of arms.
The problem to be solved: in the Terran Barracks, we rely on the input of the corresponding players to dynamically determine the units to be built, assuming that the soldiers and fire soldiers.

Train of thought: Dynamic based on the data passed, the new object of the corresponding class.
Simple Factory Pattern Example:
We put the code of the machine-gun class into a file, marine.php, and its code is as follows:

<?php
Class Marine {
The way the gun soldiers attack
Public Function Attack ()
{
Echo ' Marine attack ';
}
}
?>

We put the Flame class code into a file, firebat.php, and its code is as follows:

<?php
Class Firebat {
The method of fire soldier attack
Public Function Attack ()
{
Echo ' Firebat attack ';
}
}
?>

The contents of the main file are as follows:

<?php
Class of the Arms Builder
Class Barrackscreator {
Ways to make a class
Public Create ($createWhat)
{
According to the input parameters, dynamically load the definition file of the required class
Require_once ($createWhat. ') php ');
Dynamically returns the object of the desired class, based on the input parameters
return new $createWhat;
}
}

Create a new Class Builder object
$creator = new Barrackscreator ();

By receiving parameters to create a Flame soldier object
$troop 1 = $creator->create (' Marine ');
$troop 1->attack ();

Build a machine gun object by receiving parameters
$troop 2 = $creator->create (' Firebat ');
$troop 2->attack ();
?>

Usage Summary: Simple Factory mode encapsulates the task of a new object, and once you need to add a new return class, just modify the part of the code that is responsible for creating the new object.
Implementation summary: You need a factory that automatically returns new objects based on parameters, such as the upper Class builder Barrackscreator, where you only need to pass parameters to his production method create () without having to consider specific production details.

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.