


Understand simple factories, factory methods, and abstract factories in one article
Simple Factory Mode
Basically everyone has a music player in their mobile phone. The currently popular players are: QQ Music, Kugou Music , Sogou Music, NetEase Cloud Music, Tiantian Dongting, etc. The following is a piece of code about playing music:
if ($type == 'QQ') { $player = new QQPlayer(); } else if ($type == 'Wy') { $player = new WyPlayer(); } else if ($type == 'KG') { $player = new KGPlayer(); } else { $palyer = null; } $player->on(); // 打开播放器 $player->choiceMusic('我不配'); // 选择歌曲 $player->play(); // 开始播放
In order to make the code logic clearer and more readable, we must be good at encapsulating functionally independent code blocks into functions. According to this design idea, we can extract the conditional branches and place them in a separate method in a class. This class can be called the simple factory pattern.
Definition of simple factory pattern: A class can obtain different instances based on different parameters. Generally, these created instances have the same parent class.
Static factory pattern: Generally, we set the methods used to create different instances in the simple factory pattern as static methods to avoid creating multiple identical instances.
Let’s rewrite the above code using the simple factory pattern
class MusicPlayerFactory { public static function create ($type) { if ($type == 'QQ') { $player = new QQPlayer(); } else if ($type == 'Wy') { $player = new WyPlayer(); } else if ($type == 'KG') { $player = new KGPlayer(); } else { $player = null; } return $player; } } // 业务代码修改如下 $player = MusicPlayerFactory:create('QQ'); $player->on(); // 打开播放器 $player->choiceMusic('我不配'); // 选择歌曲 $player->play(); // 开始播放
For the above simple factory pattern, if we need to add a new music player, we will definitely modify it The create method of MusicPlayerFactory is somewhat inconsistent with the "opening and closing principle". There are not many such conditional branches, and the creation of other classes is also very simple. It is completely possible to use the simple factory pattern. If you have to remove the if branch logic and make it comply with the "opening and closing principle", then you can use the factory method to achieve it. For factory methods, it is not necessarily better than the simple factory pattern. Although its scalability is better, it sacrifices readability.
Factory method pattern
Definition: In the factory method pattern, the factory parent class is responsible for defining the public interface for creating product objects, and the factory child The class is responsible for generating specific product objects. The purpose of this is to delay the instantiation operation of the product class to the factory subclass, that is, the factory subclass is used to determine which specific product class should be instantiated.
Now we use "polymorphism" to eliminate the if branch structure of the simple factory pattern above. The implemented code is as follows:
interface IMusicPlayerFactory { static function create (); } class QQPlayerFactory implements IMusicPlayerFactory { public static function create () { return new QQPlayer(); } } class WyPlayerFactory implements IMusicPlayerFactory { public static function create () { return new WyPlayer(); } } class KGPlayerFactory implements IMusicPlayerFactory { public static function create () { return new KGPlayer(); } } // 业务代码修改如下 if ($type == 'QQ') { $player = QQPlayerFactory::create(); } else if ($type == 'Wy') { $player = WyPlayerFactory::create(); } else if ($type == 'KG') { $player = KGPlayerFactory::create(); } else { throw new \Exception('...'); } $player->on(); // 打开播放器 $player->choiceMusic('我不配'); // 选择歌曲 $player->play(); // 开始播放
As you can see, the problem has returned to the original point, and the if conditional branch structure appears again in the business code. So how to solve this problem?
We can create a simple factory for the factory class to create factory class objects. The new simple factory code is as follows:
class MusicPlayerFactoryMap { const Players = [ 'QQ' => 'QQPlayerFactory', 'Wy' => 'WyPlayerFactory', 'KG' => 'KGPlayerFactory' ]; public static function getPlayerFactory (string $type) { if (empty($type)) { return null; } return (self::Players[$type])::create(); } } // 业务代码修改如下 $palyer = MusicPlayerFactoryMap::getPlayerFactory('QQ') $player->on(); // 打开播放器 $player->choiceMusic('我不配'); // 选择歌曲 $player->play(); // 开始播放
As you can see, using the factory pattern, the structure becomes much more complex than before. We only recommend using the factory method pattern if the process of creating an instance is copied.
Abstract Factory Pattern
The abstract factory pattern is used in special scenarios and is rarely used. In the factory method pattern, specific factories are responsible for producing specific products, and each factory corresponds to a specific product. But sometimes, we need a factory that can create multiple product objects instead of a single product.
Let’s take a look at an example: The target computer factory is responsible for producing computers for sale. We know that a computer is composed of a host, a keyboard, a monitor and a mouse. Currently, the Target Computer City only produces three types of computers, low-profile, mid-range and high-profile. Computers with different configurations use different host brands, monitor brands, etc. of.
The hosts currently include: Kirin host, Thunder host, Winter host
The keyboards currently include: Rapoo, Logitech, Razer
The monitors currently include: aoc, hkc, BenQ
Mouses currently include: Logitech, Spirit Snake, and Founder
The top version of the computer is composed of Kirin host, Rapoo keyboard, AOC monitor, and Logitech mouse, and the mid-range version is composed of...
The code for the host is as follows:
interface Host { static function createHost (); } class DrHost implements Host { public static function createHost() { echo '创建冬日主机' . PHP_EOL; } } class QlHost implements Host { public static function createHost() { echo '创建麒麟主机' . PHP_EOL; } } class LtHost implements Host { public static function createHost() { echo '创建雷霆主机' . PHP_EOL; } }
Similarly, to create a keyboard, monitor, and mouse, the code will not be posted here.
Now, we define an interface for creating computers.
interface ComputerFactory { static function createHost (); static function createKeyboard (); static function createMonitor (); static function createMouse (); }
Then complete three specific factories for creating low-end, mid-end and high-end computers.
class GreatComputerFactory implements ComputerFactory { public static function createHost() { QlHost::createHost(); } public static function createKeyboard() { LbKeyboard::createKeyboard(); } public static function createMonitor() { AocMonitor::createMonitor(); } public static function createMouse() { LjMouse::createMouse(); } } class GoodComputerFactory implements ComputerFactory { public static function createHost() { LtHost::createHost(); } public static function createKeyboard() { LjKeyboard::createKeyboard(); } public static function createMonitor() { HkcMonitor::createMonitor(); } public static function createMouse() { LsMouse::createMouse(); } } class NormalComputerFactory implements ComputerFactory { public static function createHost() { DrHost::createHost(); } public static function createKeyboard() { LsKeyboard::createKeyboard(); } public static function createMonitor() { BenqMonitor::createMonitor(); } public static function createMouse() { FzMouse::createMouse(); } }
Now you can create a specific computer
class GreatComputer { public function __construct() { echo '高配电脑' . PHP_EOL; GreatComputerFactory::createHost(); GreatComputerFactory::createKeyboard(); GreatComputerFactory::createMonitor(); GreatComputerFactory::createMouse(); } } class GoodComputer { public function __construct() { echo '中配电脑' . PHP_EOL; GoodComputerFactory::createHost(); GoodComputerFactory::createKeyboard(); GoodComputerFactory::createMonitor(); GoodComputerFactory::createMouse(); } } class NormalComputer { public function __construct() { echo '低配电脑' . PHP_EOL; NormalComputerFactory::createHost(); NormalComputerFactory::createKeyboard(); NormalComputerFactory::createMonitor(); NormalComputerFactory::createMouse(); } }
The above is the detailed content of Understand simple factories, factory methods, and abstract factories in one article. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Alipay PHP...

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

How to automatically set the permissions of unixsocket after the system restarts. Every time the system restarts, we need to execute the following command to modify the permissions of unixsocket: sudo...

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

Sending JSON data using PHP's cURL library In PHP development, it is often necessary to interact with external APIs. One of the common ways is to use cURL library to send POST�...
