Archive for the 'PHP 7' Category

Factory Method with Return Typing

factorymethodIf you do a Google search for “Factory Design Pattern,” thankfully, the first hits are “Factory Method….,” the correct name of the pattern that Gamma and his associates developed as a fundamental design pattern. I am not at all impressed by nit-pickers, and lest you think me petty by touching upon the notion of “Factory” vs. “Factory Method,” I hope this post will show you why including a factory method in a Factory Method design pattern is both important and necessary.

The Factory Method: Abstract with Concrete Operations

Some of the posts about the Factory Method are more about the idea of a factory than a method within the Creator (Factory) interface. What the key is, though, is to design an interface in the Factory with both abstract and concrete elements which return a concrete Product. The details of the factoryMethod() are left up to the concrete implementations to decide which one to implement. The factoryMethod() is abstract, but with PHP7, we can establish a return type. What is a return type? When stated, it is the type of data that a method must return. In earlier versions of PHP, using type hinting, only certain types of objects could be included in a method’s arguments. Now, though, you can add a return type to a method. For example, the factoryMethod() in this example includes an IProduct return type after the closing parenthesis in the function declaration:

   abstract protected function factoryMethod():IProduct;

Like the scalar variables discussed in a pervious post that could be typed as code hints in parameters, a return value of a scalar variable such as a string means the that the method must return a string, as you can see in the IProduct implementations. However, the factoryMethod is designed to return an instance of an IProduct (the object) implementation. While common in other languages, return types are newly added feature in PHP7.

The Elegance of the Factory Method

Every time I go over the original Design Patterns in the GoF book, I find something new. One of my favorite patterns is the Template Method. The method itself is concrete but the operations within the method are abstract. The Factory Method is the opposite. The factory method is abstract, but it is called by a concrete operation defined in the interface. (I use the term interface to reference both PHP interface type classes as well as abstract class types.) To be sure, The Gang of Four, have more than a single implementation suggested for the Factory Method pattern, but in the class diagram, the method is set up in the interface (Creator) as an abstract method along with a concrete method as shown in Figure 1:

Figure 1: Factory Method class diagram

Figure 1: Factory Method class diagram

Before continuing, run the program (Play) and download the source code (Download.) The program is one I’m using to build a path from Lambda Calculus to PHP. (To run the downloaded source files, you’ll need PHP 7.)

PlayDownload

Once you have the source code downloaded and a sense of what the program produces, you’ll better understand how the Factory Method pattern makes it easy to update the “products” showing the lambda calculus and the PHP program using functional methods. The Creator participant in this pattern (IFactory) includes two methods; one abstract and one concrete as shown in the following listing:

< ?php
abstract class IFactory
{
    //This class is the 'Creator' interface in the class diagram.
 
    protected $productNow;
 
    /*
     * Factory Method--returns concrete Product--reutrns any
     * implementation of IProduct--it programs to the Interface
    */
 
    abstract protected function factoryMethod():IProduct;
 
    /*
     * The createProduct() is identified as 'anOperation()' in the class digram
     * While it is a concrete method, it returns the factoryMethod()
     * an abstract method.
    */
 
    public function createProduct():IProduct
    { 
        return $this->factoryMethod();
    }
}
?>

The IFactory abstract class may appear to be both strange and broken. How can a concrete method (createProduct) return an abstract method (factoryMethod)? Far from being broken, it’s brilliant. It means that while the createProduct() must return a factoryMethod(), the factoryMethod() can be implemented any way the developer needs following the structure of the interface.

Thoughtful Structure and Easy Update

As a Creational type of design pattern, the Factory Method may have what some consider an unnecessarily fussy (and complex) structure to get a simple product. In this example, the product returns nothing but strings with some HTML embedded to display text messages. Wouldn’t it be just as effective and a lot easier to have a single object for each product using a single interface? Or even simpler, have a single class and just add a set of properties for each string? The answer to all of those questions is, Yes, of course. However, there’s a caveat: if your product is simple; so is the solution. In the examples on this blog, I’ve tried to clarify how to build different design patterns correctly and clearly. We were stuck with the following paradox:

The clearer a design pattern example, the less useful it appears to be.

So, while generating output from strings is no great shakes, the important point is to see how simple it is to make changes using the Factory Method pattern. For example, instead of generating strings, suppose each product requires calls to a MySql database, a jQuery-based mobile UI, and a JavaScript graphic handler (not jQuery). If you look at Figure 2, you can see how this implementation follows the class diagram in Figure 1. The HTML UI and CSS file call the Client:

Figure 1: Implementation of the Factory Method pattern

Figure 1: Implementation of the Factory Method pattern

Okay, that’s a bit more complex, but the real issue is how to have several such products generated by the same program, each needing regular (e.g., daily) update and changes for several such products. By having a Factory Method take care of all of the new creations (additions and changes), you can rest assured that as the program gets bigger,as long as you follow the rules in the design pattern (attend to the rules laid down in the interfaces), not only will it be easier to maintain, but it will be less prone to bugs.

The Factory: The Method Returns Help the Developer

In creating the examples using PHP7 and the new function return types, I kept running into errors as I attempted to return product instances. The errors indicated that I was returning strings instead of objects (product instances). Because of the return typing, I was able to find the errors and return the objects, which in turn returned the strings from the products. First, look at the IFactory implementations:

< ?php
class FactoryID extends IFactory
{
    protected function factoryMethod():IProduct
    {
        $this->productNow = new LambdaID();
        return $this->productNow;
    }
}
?>
 
< ?php
class FactoryApp extends IFactory
{  
    protected function factoryMethod():IProduct
    {
        $this->productNow = new LambdaApp();
        return $this->productNow;
    }  
}
?>
 
< ?php
class FactoryPythag extends IFactory
{  
    protected function factoryMethod():IProduct
    {
        $this->productNow = new LambdaPythag();
        return $this->productNow;
    }  
}
?>

As you can see each implementation of the factory interface differs only slightly. Each calls a different product implementation. Because the createProduct() method is concrete, it does not need further implementation—even though the method calls an abstract method. (Note: Please remember that each class is saved as the class name with the “.php” extension.)
Continue reading ‘Factory Method with Return Typing’

PHP 7 Scalar Variable Type Hinting

php7WARNING: The following program only works with PHP 7 installed. After getting my first PHP 7 development platform up and running on one of my Macs, I thought it’d be a good idea to do a Q & D post on working with typed (or code hinted) scalar variables. It turns out that the type hinting with scalar variables has some interesting consequences.

Not to oversell the idea of type hinting in scalar variables, but they are important for maintaining a well-functioning program; especially one using OOP and design patterns. In this simple example, I created a class with four methods. Each of the four methods illustrate a different type of scalar type hinting; float, int, string and bool. As the most common types of variable, you can add them to the existing categories of hinted type: array, and named class/interface.

A Class to Show Off Typed Scalar

The following class uses static typing and a lambda function to illustrate that scalar variable type hinting can be used in any OOP context. Each of the first three methods, calls the next method so that you can see how all four of the scalar types work:


class Scalar
{
    private static $scalar1,$scalar2,$scalar3,$scalar4;
    //client request
    public static function request(float $num)
    {
        //float
        self::$scalar1 = $num;
        echo self::$scalar1 * 5 . '
'
; self::noFloat(4.1); }   private static function noFloat(int $singular) { //int self::$scalar2 = $singular; echo self::$scalar2 * 5 . '
'
; self::talker("Hello "); }   private static function talker(string $word) { //string self::$scalar3 = $word; echo self::$scalar3 . " world!". '
'
; self::truth((6 > 7)); }   private static function truth(bool $fact) { //bool self::$scalar4 = $fact; $result=function(bool $x) { return $x ? "It is true" : "Not true!";}; echo $result(self::$scalar4); } } Scalar::request(4.1); ?>

The initial request calls for a floating point value (float) and uses 4.1 as an argument value. The result shows 20.5. However, in the noFloat() method, an int type is used and the returned value is 20 since the argument (4.1) is automatically changed to an integer (4)–with values always rounded down. The string is a simple string (“Hello “) and the Boolean method’s, truth(), argument is the expression (6 > 7), which is false. Note also, that in the lambda function (anonymous function) assigned to the local variable $result, also has a bool data type hint. So, the type hint bool is used twice in the truth() method. By using a simple lambda function, you can better see the truth value of the Boolean.

This short post is simply to illustrate how the new scalar type hints can be used in an OOP class that includes both static and local variables as well as a lambda function. There’s more to the new PHP 7 typing that will be touched on in the near future.

PHP 7 / PHPNG: Speed and Better Data Typing

PHP7Hello PHP7

Last Wednesday (11/11/15), we drove up from Connecticut to the Boston PHP meeting where Zend’s Cal Evans gave a very informative talk on PHP 7 at the Microsoft New England Research and Development (N.E.R.D.) center next to the MIT campus. (PHP 7 is also known as PHPNG with NG = “Next Generation”.) It was well-worth the 200 mile (332K) round trip as my compadre (a Drupal guy) and I were examining every nuance of PHP 7 and what it meant for design patterns, functional programming and other PHP-based apps like Drupal and Word Press. The short version is that it means better speed. Fortunately, most of the other new features extend what we’ve been doing on this blog since its inception; namely, using mysqli instead of mysql; creating constructor functions using __construct instead of the class name; and using type hinting where possible.

Speed

I have not worried about speed for years. The bandwidth and processor speeds have regularly increased to the point where structure was more important than speed to me. Besides, there wasn’t much I could do about multi-core programming since PHP does not support concurrent development. (Maybe in version 8). I’ve already had a rant about my hosting service on my other blog; so I’ll not repeat it here; but get a hosting service that supports PHP 7.

So what about speed? It’s roughly twice what it used to be. Figure 1 shows some early timing data (which varies all over the place depending on the app you’re using). However, it does show how the speed since PHP 5.0 increased significantly. For the sake of argument, let’s say it’s about twice as fast as PHP 5.6.

Figure 1: Speed Comparisons with PHP 5.x and PHP 7

Figure 1: Speed Comparisons with PHP 5.x and PHP 7

If you’re doing professional development, you’ll want to wait until the official release of PHP 7 is out, but once it is, get yourself and your clients on a hosting service that supports PHP 7.

What Happened to PHP 6 : Abandonware

One of the questions asked at the presentation by Cal Evans was,

What happened to PHP 6?

I was thinking “vaporware” but that’s not fair nor accurate. Cal said that it was getting so on-off-on-off for a release, that it was simply abandoned to reduce confusion; so PHP 6 is “abandonware” but in fact about the only thing abandoned was the name. At the last minute one of the most important changes occurred when a huge speed improvement was introduced. Zend’s PHPNG (PHP Next Generation) engine is in head-to-head competition with HHVM (Hip-Hop Virtual Machine) from Facebook; so now with two engines competing for speed, let’s hope we all win in the speed of PHP. (Most of the speed data is from benchmarks based on the speed of numeric loops; so while speed is going to improve; don’t expect a rocket to the moon on most speed improvements.)

So What Effect Does this Have on OOP and Design Patterns?

From what I can tell; some affects to OOP may crop up, but not a lot as far as this blog is concerned. All of the examples on this blog have kept data typing strict: once a variable uses a data type, it doesn’t change. Likewise, type-hinting in parameters have forced only certain data types to be allowed in parameters. With PHP 7, type declarations are now available for scalar variables and return types. You should be able to add these declarations to any of the examples on this blog without an exception being thrown. All along we’ve been careful not to switch data types. One exception might be between integer and float types; so you might want to check there. Also, PHP 7 has a new integer divide function (intdiv()). The interval() function used up to this point will likely be replaced by the new intdiv() function where appropriate.

One of the new features that will definitely affect the way methods are written is the addition of return-type declarations. These work like the parameter declarations that have been used with object type (e.g., array, classes). So, for example, you can have something like the following:


class Infomaster
{
   private $members = 32;
   public function getMembers(): int
    {
       $groups=intdiv($this->members,5);
       return $groups;
    }
}
?>

The intdiv() function insures that the value will be an integer and the return type (int) is guaranteed. Throughout this blog, you should be able to use these kinds of type declarations without disrupting the code since care has been taken to be certain that everything is equivalent to a more strongly typed language.

What’s Next?

I’ve been waiting for the official release of PHP 7 before going ahead and finish my Sandlight CMS. This is for two reasons. My current Sandlight site is on a hosting service that is pretty far behind the curve in terms of current PHP and MySql. (e.g., I cannot use mysqli because their version of MySql is so out of date.) I’ve got to get a new hosting service, and unfortunately, the best one for what I want to do requires me to step up my IT Networking skills—get better at the command lines to work with installing PHP and the rest of LAMP files on a server that is basically carte blanche. Once I get to the point where I can program and develop, I’m good. It’s just the set-up that gives me the heebie-jeebies.

The other reason is that I want to use PHP 7 as a development language. I’m not going to worry about backward compatibility since I don’t have to support any lame web sites that some hacker built. Everything is going to remain both OOP with an increasing introduction of Functional Programming techniques that can be handled by PHP 7. I may use some Hack Language and install HHVM, but I prefer to use PHPNG with PHP 7. If I can, I’ll use both together. First, though, I have to go to the salt mines of the IT moles and get my system set up. Groan.