Beware how you trifle with your marvelous inheritance, this great land of ordered liberty, for if we stumble and fall, freedom and civilization everywhere will go down in ruin.
Everybody gets everything handed to them. The rich inherit it. I don’t mean just inheritance of money. I mean what people take for granted among the middle and upper classes, which is nepotism, the old-boy network.
Our normal waking consciousness, rational consciousness as we call it, is but one special type of consciousness, whilst all about it, parted from it by the filmiest of screens, there lie potential forms of consciousness entirely different.
If you’re new to OOP, don’t expect everything to make sense right away. As you use OOP more and more, you’ll experience little “aha!” moments when the pieces begin to come together. PHP does have important OOP features, and it has its own way of implementing these features in the language. If you are familiar with other OOP languages, you can be assured that PHP is different in places—like allowing constants to be a part of an interface. Understanding abstraction is a cornerstone in both OOP and design patterns, and the more you use it, the more sense it makes.
The notion of abstraction is so essential to both object-oriented programming and design patterns that it bears more than a fleeting consideration. The general idea of abstraction in computing is not unlike the abstractions we use every day in natural language. For example, the word dog denotes a phenomenon that has dog-like characteristics. If someone says, “look at the dog,” they use the abstraction of dog (in other words, the word dog) to indicate a concrete instance of an animal with dog-like features. By using the words dog and cat, we can differentiate one from the other and point to lots of different dogs and cats. However, if we use the word “dog” to indicate a cat, we may be corrected. “That’s not a dog. It’s a cat.” So while abstractions are general, they are specific enough so that we can differentiate specific instances.
In Object-Oriented Design with Applications, 3rd Edition (Addison-Wesley), Grady Booch, a pioneer in both OOP and design patterns, has a clear definition of abstraction that nicely sums it up:
An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of objects and thus provide crisply defined conceptual boundaries relative to the perspective of the viewer.
Abstraction is important because it allows programmers to group and classify objects. To some extent, all classes are abstractions of a set of operations on data. Keep the following in mind about abstractions:
Abstraction is the main tool used to deal with complexity. The more complex a problem, the more it requires abstractions to solve.
Think about this paradox: abstractions are concrete methods for handling complexity. We group similarities in reality (abstract concrete likeness) to make them more manageable to work with. So instead of, “my loyal, bold, furry-faced, tail-wagging, face-licking, wet-nosed friend whose name is SyntaxError,” I can say, “my dog.”
Besides regular classes, PHP also has what are called abstract classes. In OOP and design patterns, abstract classes provide an organizing mechanism for your project. An abstract class cannot be instantiated, but rather a concrete class (one you can instantiate) inherits its interface and any concrete properties from the abstract class.
Before continuing, the term interface needs to be examined. Familiar interfaces include user interfaces, hardware interfaces, and other kinds of linkages involving computer hardware and software. Another kind of interface is one that describes the outline of an object. To begin, consider a simple class with a single method:
<?php class OneTrick { private $storeHere; public function trick($whatever) { $this->storeHere=$whatever; return $this->storeHere; } } $doIt=new OneTrick(); $dataNow=$doIt->trick("This is perfect."); echo $dataNow; ?>
The central part of an interface is made up of all the signatures
in the class defined by its operations (functions). A
signature consists of an operation’s name and parameters.
Signatures also include the return data type, but because of the nature
of data typing in PHP, we’ll have to return to this third element of a
signature further on in the section Type Hinting: Almost Data Typing. Figure 2-1 shows the trick()
method’s signature.
When you take all of an object’s signatures, it is the
interface. For example, the OneTrick
class has one operation with one
signature made up of the name trick()
and a single parameter, $whatever
.
To write the trick()
function as an abstract one, include the interface but nothing
else:
abstract public function trick($whatever);
If a class has at least one abstract method, it must be an abstract class. However, an abstract class can have concrete methods as well. For example, the following class is abstract and includes an abstract method:
<?php abstract class OneTrickAbstract { public $storeHere; abstract public function trick($whatever); } ?>
In addition to the abstract method, you can see a single
variable, $storeHere
. A variable
that is part of a class is a property. In some
contexts, a reference to both properties and methods is simply
properties, but for the most part
properties refer to variables and constants
(abstract data) and methods refer to functions
(operations on the data).
PHP does not have abstract properties as such. You can declare a property with no assigned value and treat it as an abstract property, but unlike abstract methods, you are not forced to use them.
If you declare an abstract method in an abstract class, you must implement it in each child class that inherits the parent. It might help to think about methods in abstract classes as being like a contract that forces a set of hierarchies for all subclasses, so that they must all follow the same standards. For now, begin thinking of abstract classes as you would containers that can be filled with just about anything and placed on ships, trucks, and trains. The containers, like abstract classes, are part of a larger structure.
A class that inherits from a class is a child
class, and the abstract class (or any other class from which
another class has inheritance) is the parent class.
The following shows how to implement the abstract class, OneTrickAbstract
:
<?php include_once('OneTrickAbstract.php'); class OneTrickConcrete extends OneTrickAbstract { public function trick($whatever) { $this->storeHere="An abstract property"; return $whatever . $this->storeHere; } } $worker=new OneTrickConcrete(); echo $worker->trick("From an abstract origin..."); ?>
Abstract methods can be implemented in any way you want as long as
you include the method’s signature and correct visibility. In this case,
that signature includes the name “trick” and a single parameter,
$whatever
, and the visibility is
public. The following are all legitimate implementations of the trick()
method:
public function trick($whatever) { $echo $whatever; }
Or:
public function trick($whatever) { $half=$whatever/2; return $half; }
Or:
public function trick($whatever) { $this->storehere=25; $quarter=$whatever * 100; return ($quarter / $this->storehere); }
You may wonder what the point is in an abstract method if you can revise it as long as you maintain the signature and visibility. In the Inheritance section of this chapter, you will be able to see more clearly why inheriting the interface is important.
While abstract classes generally have some abstract methods, you can add as many concrete methods and properties as you want in addition to any abstract methods that must be implemented. However, an abstract class can consist of nothing but concrete methods.
PHP 5.4 has a structure called Traits that are mechanisms for code reuse where multiple inheritance is not allowed. A class may inherit one class and then at the same time use a Trait that functions something like multiple inheritance. They will not be used in the examples in this book and are mentioned here in case there may be some pattern example in another language that uses multiple inheritance that you would like to implement in PHP.
Another OOP and design pattern building block is an interface. Like most abstract classes, interfaces have abstract methods. However, you cannot include concrete methods in an interface or variables as in an abstract class. (In an exception to abstractness, you can include concrete constants in an interface, but that is a unique feature of PHP interfaces.) The salient point about interfaces is that they are important structural elements in OOP and design patterns.
To create an interface, use the interface
statement instead of class
. As a general convention, interfaces
begin with the letter I or i;
in this book, we’ll use a capital I followed by a
capital letter describing the interface. This is followed by abstract
methods, but the abstract statement is not used. The following is a
simple interface with three methods:
<?php interface IMethodHolder { public function getInfo($info); public function sendInfo($info); public function calculate($first,$second); } ?>
To implement an interface, use the implements
statement instead of extend
as is done with abstract classes. Note
that the listing uses the include_once()
function to make the interface
available to the class implementing it:
<?php include_once('IMethodHolder.php'); class ImplementAlpha implements IMethodHolder { public function getInfo($info) { echo "This is NEWS! " . $info . "<br/>"; } public function sendInfo($info) { return $info; } public function calculate($first,$second) { $calulated = $first * $second; return $calulated; } public function useMethods() { $this->getInfo("The sky is falling..."); echo $this->sendInfo("Vote for Senator Snort!") . "<br/>"; echo "You make $" . $this->calculate(20,15) . " in your part-time job<br/>"; } } $worker=new ImplementAlpha(); $worker->useMethods(); ?>
When you test the program, you should see the following output:
This is NEWS! The sky is falling... Vote for Senator Snort! You make $300 in your part-time job
Note that in addition to implementing the three methods in the
interface, the ImplementAlpha
class
includes a third method, useMethods()
. As long as you implement the
full number of methods in the interface, you can add as many other
methods and properties as you need.
While you cannot include variables in interfaces, you can include constants. In order to use constants, you need the scope resolution operator (::). The double colon operator can be used to allow access to constants, both in classes and through an interface implementation. The general format can be seen in the following code samples:
$someVariable= InterfaceName::SOME_CONSTANT;
For example, the following interface has constants used in a MySQL connection:
<?php interface IConnectInfo { const HOST ="localhost"; const UNAME ="phpWorker"; const DBNAME = "dpPatt"; const PW ="easyWay"; function testConnection(); } ?>
Implement the interface just like any other PHP interface. The values of the constants can then be passed using the scope resolution operator in the implementation:
<?php include_once('IConnectInfoMethod.php'); class ConSQL implements IConnectInfo { //Passing values using scope resolution operator private $server=IConnectInfo::HOST; private $currentDB= IConnectInfo::DBNAME; private $user= IConnectInfo::UNAME; private $pass= IConnectInfo::PW; public function testConnection() { $hookup=new mysqli($this->server, $this->user, $this->pass, $this->currentDB); if (mysqli_connect_error()) { die('bad mojo'); } print "You're hooked up Ace! <br />" . $hookup->host_info; $hookup->close(); } } $useConstant = new ConSQL(); $useConstant->testConnection(); ?>
The only method is testConnection()
, but your interface could be
made up of nothing but constants if you wanted. The values are passed to
the class properties (private variables in the example) using the name
of the interface (IConnectInfo
), the
scope resolution operator, and the name of the constant.
One of the important structural elements in the abstraction in OOP and design patterns is typing data to an interface instead of an implementation. This means that the reference to the data is through the parent class, typically an interface or abstract class. (In this context, interface is used to refer to either an interface or abstract class.)
The basic format for type hinting is as follows:
function doWork(TypeHint $someVar)...
Type hints must be the name of a class or interface. In design pattern work, an abstract class or interface is preferred because it does not bind the type of an implementation, just the structure. The following example shows an interface with two implementations of the interface and a class that uses an interface in type hinting to establish a loose but clear bind.
//IProduct.php <?php interface IProduct { function apples(); function oranges(); } ?>
//FruitStore.php <?php include_once('IProduct.php'); class FruitStore implements IProduct { public function apples() { return "FruitStore sez--We have apples. <br/>"; } public function oranges() { return "FruitStore sez--We have no citrus fruit.<br/>"; } } ?>
//CitrusStore.php <?php include_once('IProduct.php'); class CitrusStore implements IProduct { public function apples() { return "CitrusStore sez--We do not sell apples. <br/>"; } public function oranges() { return "CitrusStore sez--We have citrus fruit.<br/>"; } } ?>
//UseProducts.php <?php include_once('FruitStore.php'); include_once('CitrusStore.php'); class UseProducts { public function __construct() { $appleSauce=new FruitStore(); $orangeJuice=new CitrusStore(); $this->doInterface($appleSauce); $this->doInterface($orangeJuice); } //IProduct is type hint in doInterface() function doInterface(IProduct $product) { echo $product->apples(); echo $product->oranges(); } } $worker=new UseProducts(); ?>
When you test the UseProducts
class, the output displays
the following:
FruitStore sez--We have apples. FruitStore sez--We have no citrus fruit. CitrusStore sez--We do not sell apples. CitrusStore sez--We have citrus fruit.
What you see on the screen are different implementations of
the IProduct
interface. The
crucial feature to note is that in the doInterface()
method, the type
hint of IProduct
recognizes both of the classes that implemented the IProduct
interface. In other words,
instead of recognizing one as a FruitStore
instance and the other as a
CitrusStore
instance, it
recognizes their common interface IProduct
.
In practical terms for development, enforcing data types ensures that any object (class) used in conjunction with a given method where code hinting is used will have a given interface. Further, if an interface (either an abstract class or interface) is used as the code hint, the binding is much looser; it is bound to the interface instead of a specific implementation. As your programs get bigger, you can make changes as long as you adhere to an interface. At the same time, you can do so without getting entangled in concrete implementations.
You cannot use scalar types like string
or int
for code hints, but you can use
arrays, interfaces (as in the previous example), and classes. So
while not as flexible as some other languages, the implementation
of class typing in PHP through type hinting serves a crucial
function in OOP and design pattern programming.
Often when you read about encapsulation you will encounter the phrase information hiding. The phrase is not inaccurate, but it makes more sense once you understand encapsulation; it’s not always helpful in explaining encapsulation to begin with the concept of information hiding. Instead, a better beginning is the image of compartments. Grady Booch provides the following description:
Encapsulation is the process of compartmentalizing the elements of an abstraction that constitute its structure and behavior; encapsulation serves to separate the contractual interface of an abstraction and its implementation.
Once a big complex problem has been modularized into solvable subproblems, encapsulation is a way of taking the smaller abstractions and compartmentalizing them.
You encounter encapsulation in everyday life. Take, for example, going for a drive in your car. The car is made up of many objects, and you have little idea of how most of them work. The ignition starts the engine, but you may not know much about the battery-powered starter motor, the details of the internal combustion engine, or the electrical system in your car. You just put the key in the ignition and rotate it to start the car. The complexities of the details are hidden from you, and you have access to them in only certain ways. You are working with an encapsulated system. You don’t need to know how something works, you just need to know how to access control mechanisms—think of it as a user interface (UI) for your car.
As you are driving down the road with the window down, suppose that a car pulls up next to you, and a person sticks her arm out the window of the other car and tries to grab your steering wheel and steer your car. You can think of that as breaking encapsulation. You don’t want that to happen, so you roll up your window so that no one outside the car has access to the encapsulated cocoon of you driving your car.
In programming, encapsulation is what makes an object an object. An object has certain features that surround it so that access to its functionality is controlled by the structure of the program—just like the structure of your car controls access to its many parts. A class is encapsulated through limited access to its methods and properties. You don’t want outside influences to take control of the properties of the class and use them or change their state except through explicit routes—just like you don’t want someone to grab the steering wheel away from you. So when you encounter information hiding in the context of encapsulation, what it means is that the details of a module may be hidden so that the module may be used through the appropriate access channels and not through the module’s details.
In PHP, the term visibility refers to the access to the properties of a class. (The term access is used in other languages and accessors for the types of access.) Like other OOP languages, PHP uses three kinds of visibility: private, protected, and public. These visibilities are ways that programs can be encapsulated and accessed for use.
The easiest way to encapsulate a program element is to make it private. That means the property can be accessed only from within the same class; it’s visible only to elements in the same class. Consider the following class:
<?php class PrivateVis { private $money; public function __construct() { $this->money=200; $this->secret(); } private function secret() { echo $this->money; } } $worker=new PrivateVis(); ?>
The constructor function automatically launches the class when
the class is instantiated. Because the constructor function is part of
the PrivateVis
class, it can access
all of the private properties and methods. In order to reference a
property or method in the same class, PHP requires that the $this
statement be used with the object.
Further, the private method, secret()
, can access the private property
(variable), $money
, because they
are both part of the same class. Objects external to the class can see
only the result of the secret()
method’s output. It cannot in any way alter the state of the method or
property in the class.
By instantiating the class through the public __construct
function (constructor function),
another object has access to the private properties (variables or
constants) and methods.
While private visibility of a property provides access only to elements within the same class, protected visibility allows access to both the same class and child classes. You can incorporate protected visibility with both abstract and concrete methods. The following example shows how using an abstract class and a concrete implementation use protected visibility:
<?php //ProtectVis.php abstract class ProtectVis { abstract protected function countMoney(); protected $wage; protected function setHourly($hourly) { $money=$hourly; return $money; } } ?>
When a child class extends an abstract class with protected methods, it must implement the abstract method before using it. The child class can use the protected concrete method without further implementation:
<?php //ConcreteProtect.php include_once('ProtectVis.php'); class ConcreteProtect extends ProtectVis { function __construct() { $this->countMoney(); } protected function countMoney() { $this->wage="Your hourly wage is $"; echo $this->wage . $this->setHourly(36); } } $worker=new ConcreteProtect(); ?>
Note that the abstract method countMoney()
incorporates the inherited
setHourly()
method. All inherited
properties and methods require the $this
statement. The initial access to the
protected properties is through the public constructor
function.
While not as encapsulating as private visibility, protected visibility has the capacity to encapsulate larger structures in a program. A parent class, whether abstract or concrete, and its child classes make up the larger structure.
Access to an encapsulated object is through public visibility. To be useful, at least some of the methods in a class must be visible, even if it’s only the constructor function. Of course, all constructor methods are public. So, if your program includes a constructor function, it has public access through the instantiation of the class by an object outside the class. For example, the following code shows how a single public access method can use private methods and properties in a class:
<?php //PublicVis.php class PublicVis { private $password; private function openSesame($someData) { $this->password=$someData; if($this->password=="secret") { echo "You're in!<br/>"; } else { echo "Release the hounds!<br/>"; } } public function unlock($safe) { $this->openSesame($safe); } } $worker=new PublicVis(); $worker->unlock("secret"); $worker->unlock("duh"); ?>
Often, public methods or properties are included to maintain a
way to communicate with an object without the automatic launching of a
constructor method. In PublicVis
,
both the $password
property and
openSesame()
method are private.
However, the unlock()
method is
public and because it is part of the PublicVis
class, it can access the private
properties and method of that class.
In order to maintain encapsulation while at the same time having accessibility, OOP design suggests using getters and setters (also called accessors and mutators, respectively). Instead of accessing a class directly and either obtaining or changing property values through direct assignment, the getter/setter function does this for you. In general, the use of getters and setters must be done judiciously; too many can break encapsulation. The following example shows one use of getters and setters in a PHP class:
<?php //GetSet.php class GetSet { private $dataWarehouse; function __construct() { $this->setter(200); $got= $this->getter(); echo $got; } private function getter() { return $this->dataWarehouse; } private function setter($setValue) { $this->dataWarehouse=$setValue; } } $worker=new GetSet(); ?>
The getter/setter functions are private, and so access is encapsulated. Further, in this implementation, the setter value is inside the class and so it functions as a rather large data holder.
In dealing with data in object-oriented systems, Allen Holub, in Holub on Patterns (Apress) suggests the following:
Don’t ask for the information you need to do the work; ask the object that has the information to do the work for you.
In the GetSet
class example, instantiation of the
class:
$worker=new GetSet();
does that nicely. It does not expose the implementation details.
However, in isolation, the GetSet
class doesn’t look too useful because the only way to assign a value is
to hardcode it into the class.
In part, the purpose of design patterns is to set up the communication links between objects. Much of what passes as OOP misuses getters and setters, and making access public to them only breaks encapsulation. The following explanation, from “Single Responsibility Applied to Methods” (http://tinyurl.com/9256gey), of object-oriented programming compared to procedural programming by David Chelimsky helps clear up the role of communications in OOP:
In procedural programming, a process is expressed in one place in which a series of instructions are coded in order. Whereas in OO, a process is expressed as a succession of messages across objects. One object sends a message to another, which does part of the process and then sends a new message off to another object, which handles part of the process, etc. You modify a process by reorganizing the succession of messages rather than changing a procedure.
The process of maintaining encapsulation while communicating between objects (classes) is part of a design pattern’s job. Working out a way to establish communication without breaking encapsulation can be tricky, and so design patterns become a sort of “cheat sheet” on how to set up a program using communicating classes.
At its core, inheritance is a simple
concept. A class that extends another class has all of the other class’
properties and methods. This allows developers to create new classes that
extend the functionality of other classes. For example, if you have a
class, FurryPets
, you can extend it to
Dogs
and Cats
with both classes inheriting the properties
of FurryPets
while extending it to
differentiate Dogs
and Cats
. The following shows a simple PHP
example:
<?php //FurryPets.php class FurryPets { protected $sound; protected function fourlegs() { return "walk on all fours"; } protected function makesSound($petNoise) { $this->sound=$petNoise; return $this->sound; } } ?>
<?php //Dogs.php include_once('FurryPets.php'); class Dogs extends FurryPets { function __construct() { echo "Dogs " . $this->fourlegs() . "<br/>"; echo $this->makesSound("Woof, woof") . "<br/>"; echo $this->guardsHouse() . "<br/>"; } private function guardsHouse() { return "Grrrrr" . "<br/>"; } } ?>
<?php //Cats.php include_once('FurryPets.php'); class Cats extends FurryPets { function __construct() { echo "Cats " . $this->fourlegs() . "<br/>"; echo $this->makesSound("Meow, purrr") . "<br/>"; echo $this->ownsHouse() . "<br/>"; } private function ownsHouse() { return "I'll just walk on this keyboard." . "<br/>"; } } ?>
<?php //Client.php include_once('Dogs.php'); include_once('Cats.php'); class Client { function __construct() { $dogs=new Dogs(); $cats=new Cats(); } } $worker=new Client(); ?>
The Client
class makes the
requests, and constructor functions in the dogs
and cats
objects generate the following
output:
Dogs walk on all fours Woof, woof Grrrrr Cats walk on all fours Meow, purrr I'll just walk on this keyboard.
The fourlegs()
method
generates identical output for both objects; the makesSound()
output depends on the
argument in the parameter; and finally, each class has its own
unique method—guardsHouse()
and
ownsHouse()
.
Inheritance helps structure the different classes that may make up a program. However, in order to keep the binding between classes loose, inheritance typically comes from abstract classes, and it is shallow—a single level of child classes. If programs are bound to deep levels of inheritance of concrete classes, even simple changes in the parent classes can wreak havoc on the child classes.
At its base, polymorphism refers to many forms, but that’s not very helpful unless you understand it in the context of OOP. The real value of polymorphism is that objects with the same interface can be called to do different things. In a large complex structure (a great big program), additions and changes can blow the hinges off your program unless it has a common interface (from a parent class or interface). For example, the following program has two classes that share a common interface. The implementations of the interface are quite different:
<?php //Poly.php interface ISpeed { function fast(); function cruise(); function slow(); } class Jet implements ISpeed { function slow() { return 120; } function cruise() { return 1200; } function fast() { return 1500; } } class Car implements ISpeed { function slow() { $carSlow=15; return $carSlow; } function cruise() { $carCruise=65; return $carCruise; } function fast() { $carZoom=110; return $carZoom; } } $f22=new Jet(); $jetSlow=$f22->slow(); $jetCruise=$f22->cruise(); $jetFast=$f22->fast(); echo "<br/>My jet can take off at $jetSlow mph and cruises at $jetCruise mph. However, I can crank it up to $jetFast mph if I'm in a hurry.<br/>"; $ford=new Car(); $fordSlow=$ford->slow(); $fordCruise=$ford->cruise(); $fordFast=$ford->fast(); echo "<br/>My car pokes along at $fordSlow mph in a school zone and cruises at $fordCruise mph on the highway. However, I can crank it up to $fordFast mph if I'm in a hurry.<br/>"; ?>
The two implementations of the ISpeed
interface by the Jet
and Car
classes are very different. However, when making changes or additions
within a given structure of a program, I can request or use the interface
methods without having to worry about whether my program will crash or
not.
The easiest way to see polymorphism is in the different
implementations of an interface, as was done in the previous Poly.php example. The Jet
class simply implements each method to
return a primitive value, and the Car
class first passes a primitive value to a variable and returns the
variable’s value. Both used the same interface.
One caution about using polymorphism with PHP classes and interfaces is that the return types are not included in a PHP function’s signature. For example, a signature in C# would include both the type of return data and whether or not a return is expected. For example, consider the following C# snippet where an interface is declared:
//C# Interface interface IFace { string stringMethod(); int numMethod(int intProp); void noReturnMethod(); }
The C# language does not require the keyword function to be
included in any of its methods—just the signature, made up of the return
data type, name, and parameters (if any). So the first method—stringMethod()
—expects a string to be
returned, and any implementation of the method must include the
return
keyword. Likewise, the second method—numMethod()
—expects an integer to be returned,
and the method must include an integer parameter. Again, any
implementation requires a return
statement. However,
the third method—noReturnMethod()
—has
a return type of void. That means that no return
statement is expected in the implementation of the method. In fact, if a
return were included in the implementation of the method with a void
data type, it would cause an error and failure.
In PHP, where no return information is included in the method’s signature, you can run into possible trouble if you have mixed implementations with different data types and with and without return values. The value of polymorphism is that even though the forms may be different, you should be able to depend on the interface to guide your implementations. The more information in the interface—such as what type of behavior (returned data or not) and data type is expected—the easier it is to have different forms that still work together. In the Poly.php example, all of the methods included an integer and a return statement. So while PHP does not have a very strong signature, you can enforce it in your planning and implementation. You can do so using comment statements in your interface. For example:
//PHP Interface interface IFace { //@return string function stringMethod(); //@return integer and use integer property function numMethod($intProp); //do not use return function noReturnMethod(); }
If you have an extended virtual signature in your interfaces (including abstract classes) using comments, you can extend the advantages of a strongly typed language.
As you look at the different design patterns in this book and elsewhere, you should be aware that a good deal of the polymorphism is built right into the design pattern. For example, the Strategy design pattern includes a Strategy interface with different algorithms making up the implementations. The Strategy declares an interface that is common for the different algorithms that can be derived from Strategy. For example, a PHP Strategy design may include different implementations of the interface for different actions on a database, such as update, delete, or insert. By maintaining a common interface, new algorithms for specialized updates, selections, or searches can be added without fear of crashing the program that handles data manipulation with a MySQL table.
This chapter has included the most key OOP concepts in one place you will find in this book. However, as you read each chapter and design pattern, you will find that these concepts will be reintroduced by pointing to some aspect of the design pattern or in a PHP implementation of a design pattern. So keep in mind that what may not make sense now should become clearer as you continue with the design patterns. Chapter 3 introduces some key design pattern concepts that are based on OOP concepts and ideas.