From lightsaber in the StarCraft design mode of PHP)

Source: Internet
Author: User
Tags map class

15-status Mode

There are more than one kind of sub-categories in Starcraft. For example, a tank can be mounted, a gun can play doping, or even some passive ones. For example, after being sprayed with green liquid by the Queen of worms, the enemy's actions are slowing down.
If we operate a soldier every time, like a tank, we need to use if to judge his status.CodeThere will be a lot of IF, else or swith.
However, we can find that what we need is the behavior in a certain state. If we encapsulate these behaviors according to the state, we can reduce the number of judgments.
The problem to be solved: encapsulate the status of the tank and let the status control its own behavior.
Train of Thought: the State is used as an attribute, and the category itself only controls the change of the state. The specific behavior is defined by the state class.

Example of state mode:
<? PHP
// Tank Status Interface
Interface tankstate
{
// Tank attack method
Public Function attack ();
}

// Normal tank status
Class tankstate_tank implements tankstate
{
// Tank attack method
Public Function attack ()
{
// Simply output the current status
Echo "normal state ";
}
}

// Tank rack status
Class tankstate_siege implements tankstate
{
// Tank attack method
Public Function attack ()
{
// Simply output the current status
Echo "built up ";
}
}

// Tanks
Class Tank
{
// Status
Public $ state;
// Tank attack method
Public Function _ construct ()
{
// The newly created tank is of course normal
$ This-> state = new tankstate_tank ();
}
// Set the status. Assume that the parameter is the keyboard clicked by the player.
Public Function setstate ($ key)
{
// If you press s
If ($ key ='s ')
{
$ This-> state = new tankstate_siege ();
}
// If you press t
Elseif ($ key = 'T ')
{
$ This-> state = new tankstate_tank ();
}
}
// Tank attack method
Public Function attack ()
{
// Handle the attack by yourself in the current status
$ This-> state-> attack ();
}
}
// Create a new tank
$ Tank = new tank ();
// If an enemy passes by, the tank will attack in normal mode.
$ Tank-> attack ();
// Set up a tank
$ Tank-> setstate ('s ');
// The tank is attacked again. This is a setup mode.
$ Tank-> attack ();
?>

Summary: The Status mode encapsulates the behaviors and attributes related to the status. In addition to switching the status, you do not need to judge the current status in many other places, as long as you call the method of the current status.
Implementation Summary: use an interface to standardize the methods that the status class needs to implement. For example, the above tankstate specifies attack (). Encapsulate various states into classes, and put different methods in different States into their respective State classes, such as the attack methods above and all the status execution interfaces. The original transaction class, for example, the above tank class, is only responsible for status switching. Once a method call is required, it only needs to be handed over to the current status.

/*************************************** ************************/

16-intermediary Mode

The Starcraft upgrade system is balanced, but the relationship is complicated because many military and architectural manufacturing systems need related technical buildings.
For example, after a science station is built, all airports can build technology balls. However, if a science station is destroyed, it depends on whether there is a science station, otherwise, all airports must be unable to create technology balls.
We can solve the problem using the observer model we mentioned last time, but it seems troublesome because there are many upgrades in the space.
In fact, in essence, any upgrade generally only needs to know whether a certain building exists, so we don't have to make them have many-to-many connections, just set up an intermediary.
This is like we can buy anything at the supermarket, and the manufacturers only need to contact the supermarket, without having to contact each of our consumers directly.
The problem to be solved: do not associate buildings to reduce complexity.
Train of Thought: Set up the intermediary, every time you encounter something related to manufacturing technology, ask the intermediary.

mediator mode example:
// intermediary
class mediator
{< br> // stores the number of technology buildings. For simple description, use static attributes, in fact, various objects can also be processed.
Public static $ techbuilding;
// The system returns whether a corresponding tech building exists based on the building name represented by $ techbuildingname, for simple description, use the static attribute
Public static function istechallow ($ techbuildingname)
{< br> // if the number of tech buildings is greater than zero, true is returned, otherwise, false is returned.
return self: $ techbuilding [$ techbuildingname]> 0;
}< br> // once the technology building is built or destroyed, call this method. The parameter $ techbuildingname indicates the Building Name, $ add indicates a Boolean value, true indicates an increase (build), and false indicates a decrease (destroy)
Public static function changetech ($ techbuildingname, $ add)
{< br> // build
if ($ add)
{< br> // Add quantity
Self: $ techbuilding [$ techbuildingname] ++;
}< br> else
{< br> // quantity reduction
Self: $ techbuilding [$ techbuildingname] --;
}< BR >}

// Technology site type
Class sciencefacility
{
// Constructor
Public Function _ construct ()
{
Mediator: changetech ('sciencefacility ', true );
}
// Destructor
Public Function _ destruct ()
{
Mediator: changetech ('sciencefacility ', false );
}
}

// Airport
Class starport
{
// Method for making technology balls
Public Function createsciencevessel ()
{
// Ask the intermediary to determine whether the ball can be made
Echo mediator: istechallow ('sciencefacility ')? 'Manufacturing technology globes': 'cannot make technology globes ';
}
}

// Create a technology site
$ Sciencefacility1 = new sciencefacility ();
// Create a new technology station
$ Sciencefacility2 = new sciencefacility ();
// Create an airport
$ Starport = new starport ();
// Construct the technology ball. The result is yes.
$ Starport-> createsciencevessel ();
// A technology site is destroyed
Unset ($ sciencefacility1 );
// At this time, the technology ball is built, and the result is yes, because there is another technology station
$ Starport-> createsciencevessel ();
// Another technology site is destroyed
Unset ($ sciencefacility2 );
// No result will be returned if the technology ball is built at this time.
$ Starport-> createsciencevessel ();
?>

Purpose Summary: The intermediary mode can reduce the communication between objects and avoid code Association.
Summary: The intermediary mode is flexible. Generally, as long as there are intermediary classes and classes to be coordinated, the specific design depends on the problems encountered.

/*************************************** ************************/

17-adapter Mode

Many sub-categories of interstellar have at least one special skill. In addition, some soldiers have the same skills. For example, the Zerg troops will recover blood.
If you use skill operations and control as a method based on the general idea and put them in the definition class of each category, the code will be repeated and cannot be easily modified.
Then we will consider using the inheritance method. For example, we can design a base class for the Zerg family, which contains a method for restoring blood after injury.
When designing the hydralisk, a hacker, we can let the hacker class inherit the insect base class.
However, the diamond can be used for research and development. The diamond is not a unique feature of the Thorn. It is a feature of the insect troops on the ground. We also need to use the diamond as a public base.
The problem arises. We cannot inherit two classes from the snake class at the same time, which is not allowed by PHP.

The problem to be solved: How to reuse two classes together,
Idea: inherit a class, use the object of the new class as the attribute, and then call the method of the second class through this attribute.

Adapter mode example:
<? PHP
// Insect base class
Class Zerg
{
// Blood
Public $ blood;
// Method for restoring blood
Public Function restoreblood ()
{
// Automatically gradually restore the blood of the troops
}
}

// Drill class
Class burrow
{
// Method of drilling ground
Public Function burrowoperation ()
{
// Perform drill operations, such as stealth.
Echo 'I drilled ground ';
}
}

// The Snake type
Class hydralisk extends Zerg
{
// Store an attribute for the drill object
Public $ burrow;
// Constructor. Because PHP does not allow default values to use objects, $ burrow is assigned through initialization.
Public Function _ construct ()
{
$ This-> burrow = new burrow ();
}
// Method of drilling ground
Public Function burrowoperation ()
{
// Call the object stored in the drill property and use the drill class Method
$ This-> burrow-> burrowoperation ();
}
}
// Create a thorn
$ H1 = new hydralisk ();
// Let him drill the ground
$ H1-> burrowoperation ();
?>

Usage Summary: The adapter mode enables a class to use the functions of two basic classes at the same time, jumping out of the limitations of simple inheritance. Effective reuse of various types.
Summary: Let the new class inherit a basic class, and store the objects of other classes through the attributes of the new class, and call methods of other classes through these objects.

/*************************************** ************************/

18-Memo Mode

When we play the star task version or stand-alone vs. computer, sometimes we suddenly leave the game, or in front of the troops, we need to store the game.
So how can we save the current information? And can the stored game be recovered at any time?

The problem to be solved: stores all information about the game, if it is restored completely.
Idea: create a class dedicated to saving information and let him handle these things, just like a memorandum.
For simplicity, we will use the player information to demonstrate how to recover a player.

Example of the memento mode:
<? PHP
// Memo class
Class memento
{
// Crystal Ore
Public $ ore;
// Gas mine
Public $ gas;
// All troops of the player
Public $ troop;
// All construction objects of Players
Public $ building;
// Constructor. The parameter is the player object to be saved. The force parameter type here is the player class.
Public Function _ construct (player $ player)
{
// Save the player's crystal mine
$ This-> ORE = $ player-> ore;
// Save the player's gas mines
$ This-> gas = $ player-> gas;
// Save all the troops of the player.
$ This-> troop = $ player-> troop;
// Save all the building objects of the player
$ This-> building = $ player-> building;
}
}

// player class
class player
{< br> // crystal mining
Public $ ore;
// gas mine
Public $ gas;
// All gamer troops
Public $ troop;
// All construction objects of the player
Public $ building;
// obtain the memo object of the player
Public Function getmemento ()
{< br> return new memento ($ this);
}< br> // use the player's memo object to restore the player, the mandatory parameter type here is the memento class
Public Function restore (memento $ m)
{< br> // crystal ore
$ this-> ORE = $ M-> ore;
// gas mine
$ t His-> gas = $ M-> gas;
// All gamer troops
$ this-> troop = $ M-> troop;
// All construction objects of players
$ this-> building = $ M-> building;
}< BR >}< br> // create a player
$ p1 = new player ();
// assume that he has collected the 100 crystal mine.
$ P1-> ORE = 100;
// we save the game first, then play the game
$ M = $ P1-> getmemento ();
// assume that he has collected the 200 crystal mine
$ P1-> ORE = 200;
// We Now load the originally saved game
$ P1-> restore ($ m);
// output the crystal mine, you can see that the status has changed to the original saved state.
echo $ P1-> ore;
?>

Purpose Summary: The memo mode allows us to save information at a certain time point and restore the required information as needed, just like saving and loading a game to archive.
Summary: a memo class is required to save information. The saved class needs to generate a memo object and call a method to restore its status.

/*************************************** ************************/

19-Combination Mode

In the interstellar space, we can download maps made by others or create maps by ourselves.
When selecting which map to play, we can see that the game lists the map or map package name in the current map package.
Although map and map packages are distinguished by files and folders, we always hope to use objects for abstraction during development.
Can we simplify the differences between map and map packages?

The problem to be solved: the code for calling these two objects should be the same, that is, in many cases, there is no need to distinguish between map and map packages.
Idea: Let's make an abstract class so that the map class and the map package class inherit from it. Many methods of this class have the same name.

Composite mode example:
<? PHP
// Abstract map class
Abstract class abstractmap
{
// Map or map package name
Public $ name;
// Constructor
Public Function _ construct ($ name)
{
$ This-> name = $ name;
}
// Map or map package name. The map object has no sub-objects. Therefore, use an empty function to directly inherit from the map object.
Public Function getchildren (){}
// Add sub-objects. The map object does not have any sub-objects. Therefore, use an empty function to directly inherit from the map object.
Public Function addchild (abstractmap $ child ){}
// Display the map or map package name
Public Function showmapname ()
{
Echo $ this-> name. "<br> ";
}
// Display sub-objects. The map object has no sub-objects. Therefore, use an empty function to directly inherit from the map object.
Public Function showchildren (){}
}

// Map class: inherits the abstract map. The abstract map method is used for the moment.
Class map extends abstractmap
{

}
// Map package class, inheriting the abstract map, where we need to overload the abstract Map Method
Class mapbag extends abstractmap
{
// Set of sub-objects
Public $ childern;
// Add sub-objects and force them to use abstractmap objects. Of course, because map and map packages inherit abstractmap, they are also abstractmap objects.
Public Function addchild (abstractmap $ child)
{
$ This-> childern [] = $ child;
}
// Add sub-objects
Public Function function showchildren ()
{
If (count ($ this-> childern)> 0)
{
Foreach ($ this-> childern as $ child)
{
// Call the map or package name
$ Child-> showmapname ();
}
}
}
}

// Create a map package object. If the folder name is allied, you can check the space map directory.
$ Map1 = new mapbag ('allied ');
// Create a map object. Assume that the file name is (2) Fire Walker (which is also true)
$ MAP2 = new map ('(2) Fire Walker ');

// You can see the characteristics and usage of the combination mode.
// Assume that the following code needs to operate on two objects, but we do not know who the two objects are maps and who are map packages.
// Add a sub-object to $ map1, which is a map (4) the gardens
$ Map1-> addchild (new map ('(4) The Gardens '));
// Display its sub-objects
$ Map1-> showchildren ();

// Add a sub-object to $ MAP2, which is a map. (2) Fire Walker. No error is reported because the map inherits an empty addition method.
$ MAP2-> addchild (new map ('(2) Fire Walker '));
// Display its sub-objects without errors, because the map inherits an empty display method.
$ MAP2-> showchildren ();
?>

Purpose Summary: The combination mode can be used to process containers and objects (MAP packages and maps) in a unified manner. When other code processes these objects, it is not necessary to investigate who is the container and who is the object. The combination mode is often used to combine with the iteration mode. For example, we can use a unified method (just like the showchildren method here ), obtain all map names (including subdirectories) under the map package)
Implementation Summary: Use a base class to implement some container and object sharing methods, such as abstractmap above, and then let the container and object classes inherit the base class. Due to their different features, the corresponding methods are reloaded in the container and object classes, such as the addchild method. In this way, you can operate these two objects in a unified way.

/*************************************** ************************/

20-Bridging Mode

In object-oriented design, we generally design different classes as needed. However, if two classes need similar functions, we will encounter problems, whether to reuse or rewrite them.
What's more complicated is that if some functions require temporary conversion, it will be troublesome. For example, in the interstellar space, ground troops can drill underground and then be invisible.
However, the puppies cannot be moved down the ground, and the ground thorn can be attacked. Although different classes can be designed, the problem is that players can see their troops buried in the ground (a hole), and the enemy cannot see them.
This involves switching functions, and there are a lot of invisible things in the interstellar system, which is more frequent.

The problem to be solved: We need to temporarily switch the implementation methods of some functions, and on this basis, different call classes are different.
Train of Thought: the drill ground is divided into two implementations, and different troops are further expanded on the basis of it.

Bridge Mode example:
<? PHP
// Basic class of the Zerg family
Class Zerg
{
// Implement the basic object of the drilling ground
Public $ IMP;
// Method used to switch the basic object of a drilled hole
Public Function seibd ($ IMP)
{
$ This-> imp = $ IMP;
}
// The ground drilling method of troops, which can expand the ground drilling of basic objects
Public Function underground ()
{
$ This-> imp-> underground ();
}
}

// Puppy category
Class zergling extends Zerg
{
// Call the basic ground drill method and implement the extension. Here, the simple echo
Public Function underground ()
{
Parent: Underground ();
Echo 'puppies cannot be moved <br> ';
}
}

// The class of the ground thorn
Class lurker extends Zerg
{
// Call the basic ground drill method and implement the extension. Here, the simple echo
Public Function underground ()
{
Parent: Underground ();
Echo 'arms can attack <br> ';
}
}

// Basic ground drill Interface
Interface implementor
{
// Basic ground drilling method
Public Function underground ();
}

// Basic class of invisible Drill ground
Class invisibleimp implements implementor
{
// Basic ground drilling method
Public Function underground ()
{
Echo 'invisible and invisible <br> ';
}
}

// Basic categories that do not hide the ground, such as those that the player sees or is detected
Class visibleimp implements implementor
{
// Basic ground drilling method
Public Function underground ()
{
Echo 'a hole in the ground <br> ';
}
}
// Create a puppy
$ Z1 = new zergling ();
// The Player embeds the player in the front position. If an enemy passes by, the code is switched.
$ Z1-> seibd (New invisibleimp ());
// The enemy cannot see the puppy, but the puppy cannot attack
$ Z1-> underground ();

// Create a ground thorn
$ L1 = new lurker ();
// The Player embeds the player in the front position. If an enemy passes by, the code is switched.
$ L1-> seibd (New invisibleimp ());
// The enemy cannot see the arms, but the arms can attack the enemy.
$ L1-> underground ();

// When the enemy is in a hurry, a tech ball will fly immediately and the code will be switched
$ L1-> seibd (New visibleimp ());
// When the enemy sees the arms, the arms continues to attack the enemy.
$ L1-> underground ();
?>

purpose: the Bridge Mode separates basic implementations from specific call classes, call classes can expand more complex implementations.
Implementation Summary: some basic implementation classes are required to implement the basic methods, such as the above two drill ground classes. At the same time, we can design multiple extension call classes to extend the basic functions, such as spam and puppies, to further implement different underground behaviors.

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.