百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> PHP设计模式(新建型)
分享文章到:

PHP设计模式(新建型)

发布时间:09/01 来源:未知 浏览: 关键词:
前言

随着编程项目经历的增添,从效劳于业务逻辑到针对项目的全局设计。认识到设计模式在开发历程中 \的重要性,遵照 S.O.L.I.D 五大基准原则。它拓展了我的视野,让代码愈加灵敏,看起来愈加富有美感.\美是构建万物的哲学思想.

我们学习的设计模式分为三类:创立者模式、构造型模式、行动型模式;创立型模式与对象的创立有关;构造型模式处置类或对象的组合;而行动型模式是对类或对象怎样交互和怎样分配职责停止描写;

内容:本文介绍的是 PHP 设计模式的创立型一篇。包罗:单例模式(Singleton), 多例模式(Multiton), 工厂办法模式(Factory Method), 抽象工厂模式(Abstract Factory), 简便工厂模式(Simple Factory), 原型模式(Prototype), 对象池模式(Pool), 建筑者模式(Builder)

引荐:《PHP教程》

(一)单例模式(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)

● 定义

简便工厂模式是一个精简版的工厂模式。工厂角色-详细产品-抽象产品

● 代码示例 :

一个农场,要向市场零售水果。农场里有三种水果 iphone、葡萄,我们设想:1、水果有多种属性,每个属性都有不一样,但是,他们有共同的地方 | 生长、栽种、收货、吃。未来有大概会增添新的水果、我们需要定义一个接口来标准他们必需实现的办法.

interface fruit{
    /**
     * 生长
     */
    public function grow();
    /**
     * 栽种
     */
    public function plant();
    /**
     * 收成
     */
    public function harvest();
    /**
     * 吃
     */
    public function eat();
}
class apple implements fruit{
    //iphone树有年龄
    private $treeAge;
    //iphone有色彩
    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";
    }
    //取iphone树的年龄
    public function getTreeAge(){
        return $this->treeAge;
    }
    //设定iphone树的年龄
    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());

以上就是PHP设计模式(创立型)的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有150人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板