Factory method pattern of PHP design pattern

Last time, the simple factory doesn't belong to the twenty-three design modes of GoF. This time, it's the real guy. The famous factory method mode comes to report!

GoF class diagram explanation

Compared with simple factories, the core of factory method pattern is to postpone the implementation to subclasses. How to understand? We can take the last simple factory as a parent class, and then have a bunch of children to inherit it. The createProduct() method also becomes an abstract method in the parent class. Then all the subclasses implement this method, no longer need to use switch to judge, and the subclass directly returns an instantiated object.

GoF definition: define an interface for creating objects, and let subclasses decide which class to instantiate. Factory Method delays the instantiation of a class to its subclasses.

GoF class diagram

  • Product in class diagram is product
  • Creator in class diagram is creator
  • The creator parent class has an abstract FactoryMethod() factory method
  • All creator subclasses need to implement this factory method and return the corresponding specific product
  • The creator's parent class can have an AnOperation() operation method, which directly returns product, and can use FactoryMethod() to return, so that the external only needs to call AnOperation() uniformly

code implementation

First, commodity related interfaces and implementation classes are similar to those of simple factories:

// Commodity interface
interface Product{
    function show() : void;
}

// Commodity realization class A
class ConcreteProductA implements Product{
    public function show() : void{
        echo "I'm A.\n";
    }
}

Next are the creator's abstraction and implementation classes:

// Creator abstract class
abstract class Creator{

    // Abstract factory method
    abstract protected function FactoryMethod() : Product;

    // Operation method
    public function AnOperation() : Product{
        return $this->FactoryMethod();
    }
}

// Creator implementation class A
class ConcreteCreatorA extends Creator{
    // Implementation operation method
    protected function FactoryMethod() : Product{
        return new ConcreteProductA();
    }
}

There is an essential difference between this and the simple factory. We remove the disgusting switch and let each specific implementation class create the commodity object. Yes, single and closed. Each individual creator subclass only has coupling with one product in the factory method. It's totally unknown whether other products and other factories have cooperated with customers in this subclass.

I am a wholesaler selling mobile phones (customer Client, business side), I need a batch of mobile phones (product a), so I went to ask fux Kang (factory Creator) to help me produce them. I explained the demand with Foxconn. Foxconn agreed to let my concrete Creator a handle it. It doesn't need the main factory. You little list, sprinkle water. After a while, I needed another type of mobile phone (product b). Foxconn looked at it and then asked Foxconn Zhengzhou (concrete Creator b) to help me produce it. Anyway, they always gave me the corresponding mobile phone. And Zhengzhou factory doesn't know what Hengyang factory has produced or cooperated with me. Only I and the general factory know about it.

Full code: Factory method mode

example

Scene: just say we don't practice fake tricks and transform the last SMS sending, we still use the last few SMS senders. After all, we are already familiar with it, but it may be necessary to replace it later. If the market is like a battlefield, we still need to put the interests first. In this way, we can easily add and modify SMS providers by decoupling the factory method pattern.

Class diagram of SMS sending

code implementation

<?php

interface Message {
    public function send(string $msg);
}

class AliYunMessage implements Message{
    public function send(string $msg){
        // Call interface, send SMS
        // xxxxx
        return 'Alibaba cloud SMS (formerly Alibaba big fish) sent successfully! Message content:' . $msg;
    }
}

class BaiduYunMessage implements Message{
    public function send(string $msg){
        // Call interface, send SMS
        // xxxxx
        return 'Baidu SMS SMS sent successfully! Message content:' . $msg;
    }
}

class JiguangMessage implements Message{
    public function send(string $msg){
        // Call interface, send SMS
        // xxxxx
        return 'Aurora SMS sent successfully! Message content:' . $msg;
    }
}


abstract class MessageFactory{
    abstract protected function factoryMethod();
    public function getMessage(){
        return $this->factoryMethod();
    }
}

class AliYunFactory extends MessageFactory{
    protected function factoryMethod(){
        return new AliYunMessage();
    }
}

class BaiduYunFactory extends MessageFactory{
    protected function factoryMethod(){
        return new BaiduYunMessage();
    }
}

class JiguangFactory extends MessageFactory{
    protected function factoryMethod(){
        return new JiguangMessage();
    }
}

// Baidu cloud is needed for current business
$factory = new BaiduYunFactory();
$message = $factory->getMessage();
echo $message->send('You have a new message, please check');

Full source: SMS sending factory method

explain

  • It's completely consistent with the class diagram, basically no need to explain it. Pay attention to the characteristics of the factory method pattern, and the implementation is delayed to the subclass!!
  • Business calls need to be coupled with a Factory subclass. It's true. If you want a unified exit to call, please add a simple Factory outside. It's a question for thinking
  • Regardless of the current form, you can use an interface to define factory methods without abstract classes. Instead of the getMessage() method, you can directly call the exposed factory method externally

Next issue

Abstract factory mode, big brother is coming. The last one is always the strongest. Let's see elder brother's ability!

===============

Official account: hard core project manager

Add wechat / QQ friends: [darkmaterzycoder / 149844827] free PHP and project management learning materials

Tags: Mobile PHP

Posted on Mon, 15 Jun 2020 02:36:33 -0400 by kucing