The combination mode in PHP

Source: Internet
Author: User

Just read the "in-depth PHP object-oriented, mode and practice," a book of the combination of the content, in order to deepen understanding and memory, so began to write this blog.

To facilitate subsequent comprehension, two concepts, local objects, and composite objects are introduced here first.

Local object: Cannot combine other objects into an object on its own internal property. That is, objects that cannot be combined with other objects.

Composite objects: You can group other objects into objects on their own internal properties. That is, objects that can combine other objects.

Note: Storing a reference to an object B object in a property of object A indicates that a has a combined relationship with B, where a combines b into itself.

First, we introduce the combined pattern by giving the following business requirements:

The business unit wants to develop a battle game similar to the red alert, with two initial local combat units: Shooter (Archer) and laser cannon (Lasercannon), combined combat units can have a variety of combo combat units (composed of two local units), Or a combined combat unit composed of a combination unit and a local combat unit, where there are many combinations of objects, with different sub-objects. Both the combined unit and the local unit have the properties common to the combat unit (attack ability, mobile ability and defense ability). The property value in the combined cell is the same as the value of the corresponding property of its sub-object. Because the sub-object of the composition object needs to change according to the situation constantly, then its corresponding property values also need to be constantly updated and changed, here we need to adopt what kind of combination of test in order to easily update and get the property values of the composite object, here we need to use the combination of today's model.

Combination mode:

1. Definition: Combine a set of objects into a structure that can be used like a single object. (That is, you can get property values in a composite object as easily as a local object)

2. Classification: The combination mode is divided into two kinds, transparent mode and safe mode.

2, the realization method:

Analysis: How can a composite object be easily computed with attribute values? If you can easily get the corresponding property in its child objects, you can do so by summing it. So how to conveniently get the corresponding property values in the Sub-object? The main challenge here is how to know which sub-objects are included, but the simplest way is to keep a reference to the sub-object in the composition object, store all the child objects in an array of data structures, so that we can iterate through the array in the method that gets the value of the property, and then sum up the property values of the combined object. The specific code is as follows:

Abstract classunit{//The attack attribute value used to get the combat unit    Abstract functionbomstrength ();}//Local combat Unit (shooter)classArcherextendsunit{functionbomstrength () {return4; }}//Local combat unit (laser cannon)classLasercannonunitextendsunit{functionbomstrength () {return44; }}
//Combo combat unit classArmyextendsunit{Private $units=Array();//used to store child objects//used to add child objects functionAddunit (Unit$unit) { Array_push($this->units,$unit); } //used to calculate attack attribute values functionbomstrength () {$ret= 0; foreach($this->units as $unit) { $ret+=$unit-bomstrength (); } }}

The above is the code that satisfies our needs, but more often the client does not need to distinguish between army, unit, or other composite objects, and functionally, these combined patterns are the same, with the ability to move, attack, and defend. These features make it easy to imagine that they share the same type of family (which is the combined pattern).

Here's how to implement both transparent and secure in composite mode:

Transparent mode:

Abstract classunit{AbstractFuncton Addunit (Unit$unit); Abstract functionRemoveunit (Unit$unit); Abstract functionbomstrength ();}Army class extendsunit{Private $units=Array();  Public functionAddunit (Unit$unit)    {        if(In_array($unit,$this->units,true))        {            return; }    }     Public functionRemoveunit ($unit)    {        $this->units =Array_udiff($this->units, Array ($unit),function($a,$b) {return($a===$b)? 0:1}); }     Public functionbomstrength () {$ret= 0; foreach($this->units as $unit)        {            $ret+=$unit-bomstrength (); }    }}

Here Army can save any type of unit object, including army itself or local objects such as Archer or Lasercannon. Since all unit objects are guaranteed to support the Bomstrength method, we can calculate the attack strength of the army::bomstrength by simply traversing the $units development and invoking the Bomstrength method of each Unit object.

But in fact, we do not need to add a Unit object on archer, so when Archer or Lasercannon this local object calls the Addunit or Removeunit method to throw an exception, we can specify in the abstract class these two methods throw an exception, These two functions are overridden only in a composite object. This is the transparent mode in the composite mode, the feature is transparent to the client, whether it is a local object or a combination of objects, the method is public, but there are obvious shortcomings: the Authority object calls Removeunit or Addunit method, although the method exists, but will only give an exception, This is what we do not want to encounter in the run, there is no way to achieve a common parent class, without the unexpected error behavior of the method. Of course there is, this is the volume combination mode of another mode, Safe mode.

Safe Mode:

Abstract classunit{
function Getcomposite ()
{
return null;
} Abstract functionbomstrength ();}classCompositeunitextendsunit{Private $units=Array(); functionGetcomposite () {return $this; } protected functionunits () {return $this-units; } Public functionRemoveunit (Unit$unit) { $this->units =Array_udiff($this->units,Array($unit),function($a,$b) {return($a===$b)? 0:1} ); } Public functionAddunit (Unit$unit) { if(In_array($unit,$this->units,true)) { return; } $this->units[] =$unit; }}

As shown above: We have added a sub-abstract class for the composite object, this sub-abstract class has more than one method Getcomposite, this method is used to identify whether the client is a composite object, if so, return this object, if not, then return NULL, In this way, the client calls the Getcomposite method before calling the Aaunit or Removeunit method to know the type of the object and makes the appropriate operation, which solves the problem in transparent mode perfectly.

However, the two models themselves are not superior or inferior, the specific use of which needs to be differentiated according to the business.

Need to worry about the cost of the combined mode if the subclass is nested too much, a loop may blow up the system, so here are some tips for using the combo pattern:

1) You need to cache the property values of the subclasses in the parent set object, which can reduce the overhead, and even so, you need to ensure that the cached values do not expire, that is, you need to update the expired cache in real time.

2) on the object persistence, the combined mode is not suitable for storing in a relational database, because this will increase the overhead of SQL queries as the depth of nesting of the system increases, so that the system overhead of updating the addition and removal of child objects will be larger. However, the object relationship in the combined mode is suitable for storing in XML, and the tree structure in XML is exactly the same as that of the composite object.

Well, the personal understanding of the combination of the mode of this, the content will be constantly updated, and strive to slowly understand the true meaning of the various models.

The combination mode in PHP

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.