display_picture.php?url=https%3A%2F%2Fmmbiz.qpic.jpg

php中文网最新课程
每日17点准时技术干货分享
display_picture.php?url=https%3A%2F%2Fmmbiz.qpic.jpg

display_picture.php?url=https%3A%2F%2Fmmbiz.qpic.jpg


前言随着编程项目经验的增加,从服务于业务逻辑到针对项目的全局设计。认识到设计模式在开发过程中 \的重要性,遵循 S.O.L.I.D 五大基准原则。它拓展了我的视野,让代码更加灵活,看起来更加富有美感.\美是构建万物的哲学思想.我们学习的设计模式分为三类:创建者模式、结构型模式、行为型模式;创建型模式与对象的创建有关;结构型模式处理类或对象的组合;而行为型模式是对类或对象怎样交互和怎样分配职责进行描述;内容:本文介绍的是 PHP 设计模式的创建型一篇。包括:单例模式(Singleton), 多例模式(Multiton), 工厂方法模式(Factory Method), 抽象工厂模式(Abstract Factory), 简单工厂模式(Simple Factory), 原型模式(Prototype), 对象池模式(Pool), 建造者模式(Builder)(一)单例模式(Singleton)● 定义保证一个类只有一个实例,并且提供一个访问它的全局访问点。系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。● 代码示例

class Singleton{
    /**
    * @var Singleton
    */
    private static $instance;
    /**
    * 不允许从外部调用以防止创建多个实例
    * 要使用单例,必须通过 Singleton::getInstance() 方法获取实例
    */
    private function __construct(){
    }
    /**
    * 通过懒加载获得实例(在第一次使用的时候创建)
    */
    public static function getInstance(): Singleton{
        if (null === static:instance) {
            static:instance = new static();
        }
        return static:instance;
    }
    /**
    * 防止实例被克隆(这会创建实例的副本)
    */
    private function __clone(){
    }
    /**
    * 防止反序列化(这将创建它的副本)
    */
    private function __wakeup(){
    }
}(二)多例模式(Multiton)
● 定义
在多例模式中,多例类可以有多个实例,而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。1. 通过实例容器保存容器。2. 利用私有构造阻止外部构造。3. 提供getInstantce()方法获取实例.
● 代码示例  两个对象通过一个类进行多次实例化

abstract class Multiton {
    private static $instances = array();
    public static function getInstance() {
        $key = get_called_class() . serialize(func_get_args());
        if (!isset(self:instances[$key])) {
            $rc = new ReflectionClass(get_called_class());
            self:instances[$key] = $rc->newInstanceArgs(func_get_args());
        }
        return self:instances[$key];
    }
    /**
     * 该私有对象阻止实例被克隆
     */
    private function __clone(){
    }
    /**
     * 该私有方法阻止实例被序列化
     */
    private function __wakeup(){
    }
}
class Hello extends Multiton {
    public function __construct($string = 'World') {
        echo "Hello $string\n";
    }
}
class GoodBye extends Multiton {
    public function __construct($string = 'my', $string2 = 'darling') {
        echo "Goodbye $string $string2\n";
    }
}
$a = Hello::getInstance('World');
$b = Hello::getInstance('bob');
// $a !== $b
$c = Hello::getInstance('World');
// $a === $c
$d = GoodBye::getInstance();
$e = GoodBye::getInstance();
// $d === $e
$f = GoodBye::getInstance('your');
// $d !== $f
(三)工厂方法模式(Factory Method)
● 定义
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类
● 代码示例 :小成有一间塑料加工厂(仅生产 A 类产品);随着客户需求的变化,客户需要生产 B 类产品。改变原有塑料加工厂的配置和变化非常困难,假设下一次客户需要再发生变化,再次改变将增大非常大的成本;小成决定置办塑料分厂 B 来生产 B 类产品。

abstract class Product{
    public abstract function Show();
}
//具体产品A类
class  ProductA extends  Product{
    public function Show() {
        echo "生产出了产品A";
    }
}
//具体产品B类
class  ProductB extends  Product{
    public function Show() {
        echo "生产出了产品B";
    }
}
abstract class Factory{
    public abstract function Manufacture();
}
//工厂A类 - 生产A类产品
class  FactoryA extends Factory{
    public function Manufacture() {
        return new ProductA();
    }
}
//工厂B类 - 生产B类产品
class  FactoryB extends Factory{
    public function Manufacture() {
        return new ProductB();
    }
}
(四)抽象工厂模式(Abstract Factory)
● 定义
在不指定具体类的情况下创建一系列相关或依赖对象。 通常创建的类都实现相同的接口。 抽象工厂的客户并不关心这些对象是如何创建的,它只是知道它们是如何一起运行的。
● 代码示例 : 有两个工厂,A 工厂负责运输,B 工厂生产数码产品.

interface Product{
    public function calculatePrice(): int;
}
class ShippableProduct implements Product{
    /**
     * @var float
     */
    private $productPrice;
    /**
     * @var float
     */
    private $shippingCosts;
    public function __construct(int $productPrice, int $shippingCosts){
        $this->productPrice = $productPrice;
        $this->shippingCosts = $shippingCosts;
    }
    public function calculatePrice(): int{
        return $this->productPrice + $this->shippingCosts;
    }
}
class DigitalProduct implements Product{
    /**
     * @var int
     */
    private $price;
    public function __construct(int $price){
        $this->price = $price;
    }
    public function calculatePrice(): int{
        return $this->price;
    }
}
class ProductFactory{
    const SHIPPING_COSTS = 50;
    public function createShippableProduct(int $price): Product{
        return new ShippableProduct($price, self::SHIPPING_COSTS);
    }
    public function createDigitalProduct(int $price): Product{
        return new DigitalProduct($price);
    }
}
(五)简单工厂模式(Simple Factory)● 定义简单工厂模式是一个精简版的工厂模式。工厂角色-具体产品-抽象产品● 代码示例 :一个农场,要向市场销售水果。农场里有三种水果 苹果、葡萄,我们设想:1、水果有多种属性,每个属性都有不同,但是,他们有共同的地方 | 生长、种植、收货、吃。将来有可能会增加新的水果、我们需要定义一个接口来规范他们必须实现的方法.

interface fruit{
    /**
     * 生长
     */
    public function grow();
    /**
     * 种植
     */
    public function plant();
    /**
     * 收获
     */
    public function harvest();
    /**
     * 吃
     */
    public function eat();
}
class apple implements fruit{
    //苹果树有年龄
    private $treeAge;
    //苹果有颜色
    private $color;
    public function grow(){
        echo "grape grow";
    }
    public function plant(){
        echo "grape plant";
    }
    public function harvest(){
        echo "grape harvest";
    }
    public function eat(){
        echo "grape eat";
    }
    //取苹果树的年龄
    public function getTreeAge(){
        return $this->treeAge;
    }
    //设置苹果树的年龄
    public function setTreeAge($age){
        $this->treeAge = $age;
        return true;
    }
}
class grape implements fruit{
    //葡萄是否有籽
    private $seedLess;
    public function grow(){
        echo "apple grow";
    }
    public function plant(){
        echo "apple plant";
    }
    public function harvest(){
        echo "apple harvest";
    }
    public function eat(){
        echo "apple eat";
    }
    //有无籽取值
    public function getSeedLess(){
        return $this->seedLess;
    }
    //设置有籽无籽
    public function setSeedLess($seed){
        $this->seedLess = $seed;
        return true;
    }
}
class farmer{
    //定义个静态工厂方法
    public static function factory($fruitName){
        switch ($fruitName) {
            case 'apple':
                return new apple();
                break;
            case 'grape':
                return new grape();
                break;
            default:
                throw new badFruitException("Error no the fruit", 1);
                break;
        }
    }
}
class badFruitException extends Exception{
    public $msg;
    public $errType;
    public function __construct($msg = '' , $errType = 1){
        $this->msg = $msg;
        $this->errType = $errType;
    }  
}
/**
* 获取水果实例化的方法
*/
try{
    $appleInstance = farmer::factory('apple');
    var_dump($appleInstance);
}catch(badFruitException $err){
    echo $err->msg . "_______" . $err->errType;
}(六)原型模式(Prototype)
● 定义
相比正常创建一个对象 (new Foo () ),首先创建一个原型,然后克隆它会更节省开销。
● 代码示例 : 为每一本书设置标题

abstract class BookPrototype{
    /**
    * @var string
    */
    protected $title = 0;
    /**
    * @var string
    */
    protected $category;
    abstract public function __clone();
    public function getTitle(): string{
        return $this->title;
    }
    public function setTitle($title){
       $this->title = $title;
    }
}
class BarBookPrototype extends BookPrototype{
    /**
    * @var string
    */
    protected $category = 'Bar';
    public function __clone(){
    }
}
class FooBookPrototype extends BookPrototype{
    /**
    * @var string
    */
    protected $category = 'Foo';
    public function __clone(){
    }
}
$fooPrototype = new FooBookPrototype();
$barPrototype = new BarBookPrototype();
for ($i = 5; $i < 10; $i++) {
    $book = clone $fooPrototype;
    $book->setTitle('Foo Book No ' . $i);
    var_dump(new FooBookPrototype == $book);
}
for ($i = 0; $i < 5; $i++) {
    $book = clone $barPrototype;
    $book->setTitle('Bar Book No ' . $i);
    var_dump(new BarBookPrototype == $book);
}
(七)对象池模式(Pool)
● 定义
对象池可以用于构造并且存放一系列的对象并在需要时获取调用。在初始化实例成本高,实例化率高,可用实例不足的情况下,对象池可以极大地提升性能。在创建对象(尤其是通过网络)时间花销不确定的情况下,通过对象池在短期时间内就可以获得所需的对象。
● 代码示例

class Factory {
    protected static $products = array();
    public static function pushProduct(Product $product) {
        self:products[$product->getId()] = $product;
    }
    public static function getProduct($id) {
        return isset(self:products[$id]) ? self:products[$id] : null;
    }
    public static function removeProduct($id) {
        if (array_key_exists($id, self:products)) {
            unset(self::$products[$id]);
        }
    }
}
Factory::pushProduct(new Product('first'));
Factory::pushProduct(new Product('second'));
print_r(Factory::getProduct('first')->getId());
// first
print_r(Factory::getProduct('second')->getId());
// second(八)建造者模式(Builder)
● 定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
● 2)代码示例  建造相同标准的卡车和汽车。类似于变形金刚,相同的零件进行不同的组合.
● 分为 Director 导演者,负责构建、BuilderInterface 构建接口,规范建造标准、TruckBuilder 构建卡车类 CarBuilder 构建汽车类
Vehicle 零部件公共类、Truck Car Engine Wheel Door 零部件类、DirectorTest 测试类

class Director{
    public function build(BuilderInterface $builder): Vehicle{
        $builder->createVehicle();
        $builder->addDoors();
        $builder->addEngine();
        $builder->addWheel();
        return $builder->getVehicle();
    }
}
interface BuilderInterface{
    public function createVehicle();
    public function addWheel();
    public function addEngine();
    public function addDoors();
    public function getVehicle(): Vehicle;
}
class TruckBuilder implements BuilderInterface{
    /**
    * @var Truck
    */
    private $truck;
    public function addDoors(){
        $this->truck->setPart('rightDoor', new Door());
        $this->truck->setPart('leftDoor', new Door());
    }
    public function addEngine(){
        $this->truck->setPart('truckEngine', new Engine());
    }
    public function addWheel(){
        $this->truck->setPart('wheel1', new Wheel());
        $this->truck->setPart('wheel2', new Wheel());
        $this->truck->setPart('wheel3', new Wheel());
        $this->truck->setPart('wheel4', new Wheel());
        $this->truck->setPart('wheel5', new Wheel());
        $this->truck->setPart('wheel6', new Wheel());
    }
    public function createVehicle(){
        $this->truck = new Truck();
    }
    public function getVehicle(): Vehicle{
        return $this->truck;
    }
}
class CarBuilder implements BuilderInterface{
    /**
    * @var Car
    */
    private $car;
    public function addDoors(){
        $this->car->setPart('rightDoor', new Door());
        $this->car->setPart('leftDoor', new Door());
        $this->car->setPart('trunkLid', new Door());
    }
    public function addEngine(){
        $this->car->setPart('engine', new Engine());
    }
    public function addWheel(){
        $this->car->setPart('wheelLF', new Wheel());
        $this->car->setPart('wheelRF', new Wheel());
        $this->car->setPart('wheelLR', new Wheel());
        $this->car->setPart('wheelRR', new Wheel());
    }
    public function createVehicle(){
        $this->car = new Car();
    }
    public function getVehicle(): Vehicle{
        return $this->car;
    }
}
abstract class Vehicle{
    /**
    * @var object[]
    */
    private $data = [];
    /**
    * @param string $key
    * @param object $value
    */
    public function setPart($key, $value){
        $this->data[$key] = $value;
    }
}
class Truck extends Vehicle{
}
class Car extends Vehicle{
}
class Engine extends Vehicle{
}
class Wheel extends Vehicle{
}
class Door extends Vehicle{
}
class DirectorTest{
    public function testCanBuildTruck(){
        $truckBuilder = new TruckBuilder();
        return (new Director())->build($truckBuilder);
    }
    public function testCanBuildCar(){
        $carBuilder = new CarBuilder();
        return (new Director())->build($carBuilder);
    }
}
$directorTest = new DirectorTest();
var_dump($directorTest->testCanBuildTruck());
var_dump($directorTest->testCanBuildCar());

                               
登录/注册后可看大图


-END-

声明:本文选自「 php中文网 」,搜索「 phpcnnew 」即可关注!

温馨提示:
1、在论坛里发表的文章仅代表作者本人的观点,与本网站立场无关。
2、论坛的所有内容都不保证其准确性,有效性,时间性。阅读本站内容因误导等因素而造成的损失本站不承担连带责任。
3、当政府机关依照法定程序要求披露信息时,论坛均得免责。
4、若因线路及非本站所能控制范围的故障导致暂停服务期间造成的一切不便与损失,论坛不负任何责任。
5、注册会员通过任何手段和方法针对论坛进行破坏,我们有权对其行为作出处理。并保留进一步追究其责任的权利。




上一篇:PHP新分支:P++,你还敢说php是弱类型语言吗?
下一篇:[PHP编程]数据发送与获取&amp;运算符&amp;加法计算器
回复

使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies |上传

    本版积分规则

    该用户从未签到

    发表于 2019-10-4 20:51:36 | 显示全部楼层
    沙发
    好好 学习了 确实不错
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-10-6 17:22:40 | 显示全部楼层
    板凳
    找到好贴不容易,我顶你了,谢了
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-10-6 23:55:38 | 显示全部楼层
    地板
    真是 收益 匪浅
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2019-12-18 23:29
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2019-10-9 04:18:33 | 显示全部楼层
    5#
    没看完~~~~~~ 先顶,好同志
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-10-11 05:10:56 | 显示全部楼层
    6#
    学习了,谢谢分享、、、
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-10-11 17:34:39 | 显示全部楼层
    7#
    写的真的很不错
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-10-11 19:12:12 | 显示全部楼层
    8#
    相当不错,感谢无私分享精神!
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-10-14 23:31:11 | 显示全部楼层
    9#
    不知该说些什么。。。。。。就是谢谢
    回复

    使用道具 举报

    该用户从未签到

    发表于 2019-10-15 19:59:39 | 显示全部楼层
    10#
    真是 收益 匪浅
    回复

    使用道具 举报

    • 售后服务
    • 关注我们
    • 社区新手

    QQ|关于我们|手机版|小黑屋|多资源交流论坛 ( 鲁ICP备18025140号-4 )

    多资源网手游源码交流 X3.4  © 2018-2020 DuoZy.Cn