ホームページ > バックエンド開発 > PHPチュートリアル > PHPデザインパターン(クリエイティブ)

PHPデザインパターン(クリエイティブ)

藏色散人
リリース: 2023-04-07 11:36:01
転載
2685 人が閲覧しました

序文

ビジネス ロジックの提供からプロジェクト全体の設計に至るまで、プログラミング プロジェクトの経験が増えるにつれて。開発プロセスにおけるデザインパターンの重要性を認識し、S.O.L.I.D.の 5 つのベンチマーク原則に従います。それは私の視野を広げ、コードをより柔軟にし、より美しく見せます。\美とは、あらゆるものを構築するための哲学的な考え方です。

私たちが学ぶデザイン パターンは、次の 3 つのカテゴリに分類されます: クリエーター パターンおよび構造パターン、動作パターン。作成パターンはオブジェクトの作成に関連します。構造パターンはクラスまたはオブジェクトの組み合わせを扱います。動作パターンはクラスまたはオブジェクトがどのように相互作用し、責任を割り当てるかを説明します。

コンテンツ: この記事では、PHP デザイン パターンの作成について紹介します。含まれるもの: シングルトン モード、マルチトン モード、ファクトリ メソッド モード、抽象ファクトリ モード、シンプル ファクトリ モード、プロトタイプ モード、オブジェクト プール モード (プール)、ビルダー パターン (ビルダー)

推奨: 「PHP チュートリアル#」 ##"

(1) シングルトン パターン (Singleton)

# 定義

# クラスのインスタンスが 1 つだけであることを確認し、グローバル アクセスを提供するアクセスするためのポイントを指定します。システム メモリにはこのクラスのオブジェクトが 1 つだけあるため、システム リソースが節約されます。頻繁に作成および破棄する必要がある一部のオブジェクトについては、シングルトン モードを使用するとシステム パフォーマンスが向上します。

# コード例

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()
    {
    }
}
ログイン後にコピー

(2) マルチインスタンスモード (Multiton) #● マルチインスタンスでの定義

mode では、マルチインスタンス クラスは複数のインスタンスを持つことができ、マルチインスタンス クラスは独自のインスタンスを作成して管理し、独自のインスタンスを外部に提供する必要があります。 1. インスタンス コンテナを介してコンテナを保存します。 2. 外構工事を避けるために民間建築物を使用する。 3. getInstantce() メソッドを使用してインスタンスを取得します。

# コード例 1 つのクラスを通じて 2 つのオブジェクトを複数回インスタンス化する

#
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
ログイン後にコピー

(3) ファクトリ メソッド パターン (ファクトリ メソッド) )

## 定義

# クラスのインスタンス化 (特定の製品の作成) をファクトリ クラスのサブクラス (特定のファクトリ) に遅らせます。つまり、サブクラスがどちらを決定するかを決定します。インスタンスはどのクラスを変更 (作成) する必要があります。

# コード例: 小城市にはプラスチック加工工場 (クラス A 製品のみを生産) があり、顧客のニーズの変化に応じて、顧客はクラス B 製品を生産する必要があります。元のプラスチック加工工場の構成を変更して変更することは非常に困難であり、次回顧客のニーズが変わると仮定すると、再度変更するとコストが非常に増加するため、Xiaocheng はクラス 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();
    }
}
ログイン後にコピー

(4) 抽象ファクトリ パターン (Abstract Factory)

● 定義

一連の関連オブジェクトまたは依存オブジェクトを作成します。通常、クラスは同じインターフェイスを実装するように作成されます。抽象ファクトリーのクライアントは、オブジェクトがどのように作成されるかを気にせず、オブジェクトがどのように連携して機能するかを知っているだけです。

# コード例: 2 つの工場があり、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);
    }
}
ログイン後にコピー

(5) シンプルファクトリーモード (Simple Factory)

# 定義

#シンプル ファクトリ パターンは、ファクトリ パターンの合理化されたバージョンです。工場の役割 - 具体的な製品 - 抽象的な製品

#コード例:

ある農場は、果物を市場に販売したいと考えています。農場にはリンゴとブドウの 3 種類の果物があります。私たちは次のように想像します: 1. 果物には複数の属性があり、それぞれの属性は異なりますが、共通点があります (成長、植え、収穫、食べる)。将来的に新しいフルーツが追加される可能性があるため、それらが実装する必要があるメソッドを標準化するためのインターフェイスを定義する必要があります。

通常のオブジェクト作成 (new Foo ()) と比較して、最初にプロトタイプを作成してからクローンを作成する方がコスト効率が高くなります。

# コード例: 書籍ごとにタイトルを設定

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;
}
ログイン後にコピー
(7) オブジェクト プール モード (Pool)

● 定義

オブジェクト プールを使用すると、一連のオブジェクトを構築して保存し、必要に応じて呼び出しを取得できます。インスタンスの初期化コストが高く、インスタンス化率が高く、使用可能なインスタンスが不十分な状況では、オブジェクト プールによってパフォーマンスが大幅に向上します。オブジェクトの作成に必要な時間が不確実な状況 (特にネットワーク上) では、オブジェクト プールを通じて必要なオブジェクトを短時間で取得できます。

# コード例

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(&#39;Foo Book No &#39; . $i);
    var_dump(new FooBookPrototype == $book);
}
for ($i = 0; $i < 5; $i++) {
    $book = clone $barPrototype;
    $book->setTitle(&#39;Bar Book No &#39; . $i);
    var_dump(new BarBookPrototype == $book);
}
ログイン後にコピー
(8) ビルダー パターン (Builder)

#● 定義

複雑なオブジェクトを変換します。はその表現から分離されているため、同じビルド プロセスで異なる表現を作成できます。

#● 2) コード例 同じ規格のトラックと乗用車をビルドします。 Transformers と同様に、同じパーツをさまざまな方法で組み合わせることができます。

# 構築を担当する Director、インターフェースの構築と構築基準の標準化を行う BuilderInterface、トラックのクラスを構築する TruckBuilder に分かれています。 .CarBuilder は車のクラスを構築します。

Vehicle Parts パブリック クラス、Truck Car Engine Wheel Door Parts クラス、DirectorTest テスト クラス

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(&#39;first&#39;));
Factory::pushProduct(new Product(&#39;second&#39;));
print_r(Factory::getProduct(&#39;first&#39;)->getId());
// first
print_r(Factory::getProduct(&#39;second&#39;)->getId());
// second
ログイン後にコピー

以上がPHPデザインパターン(クリエイティブ)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:learnku.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート