ホームページ  >  記事  >  バックエンド開発  >  単純なファクトリ、ファクトリ メソッド、および抽象ファクトリを 1 つの記事で理解する

単純なファクトリ、ファクトリ メソッド、および抽象ファクトリを 1 つの記事で理解する

齐天大圣
齐天大圣オリジナル
2020-07-31 08:39:221904ブラウズ

シンプル ファクトリー モード

基本的に誰もが携帯電話に音楽プレーヤーを持っています。現在人気のあるプレーヤーは次のとおりです: QQ Music、Kugou Music、Sogou Music、 NetEase Cloud 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();  // 开始播放

コード ロジックをより明確で読みやすくするには、機能的に独立したコード ブロックを関数にカプセル化するのが上手でなければなりません。この設計思想によれば、条件分岐を抽出してクラス内の別のメソッドに配置することができます。このクラスは、単純なファクトリ パターンと呼ぶことができます。

単純なファクトリ パターンの定義: クラスは、異なるパラメータに基づいて異なるインスタンスを取得できます。通常、これらの作成されたインスタンスは同じ親クラスを持ちます。

静的ファクトリ パターン: 一般に、複数の同一インスタンスの作成を避けるために、単純なファクトリ パターンで異なるインスタンスを作成するために使用されるメソッドを静的メソッドとして設定します。

単純なファクトリ パターンを使用して上記のコードを書き直してみましょう

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();  // 开始播放

上記の単純なファクトリ パターンの場合、新しい音楽プレーヤーを追加する必要がある場合は、必ず変更しますMusicPlayerFactory の create メソッドは、「開閉の原則」と多少矛盾しています。条件分岐も少なく、他のクラスの作成も非常に簡単で、シンプルなファクトリパターンを利用することも十分に可能です。 if 分岐ロジックを削除して「開閉原則」に準拠させる必要がある場合は、ファクトリ メソッドを使用してそれを実現できます。ファクトリ メソッドの場合、単純なファクトリ パターンよりも優れているとは限りません。スケーラビリティは優れていますが、可読性が犠牲になります。

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

定義: ファクトリ メソッド パターンでは、ファクトリの親クラスが製品オブジェクトを作成するためのパブリック インターフェイスを定義します。 、およびファクトリの子 このクラスは、特定の製品オブジェクトの生成を担当します。この目的は、製品クラスのインスタンス化操作をファクトリのサブクラスに遅らせることです。つまり、ファクトリのサブクラスは、どの特定の製品クラスを作成するかを決定するために使用されます。インスタンス化されました。

ここで、「ポリモーフィズム」を使用して、上記の単純なファクトリ パターンの if 分岐構造を削除します。実装されたコードは次のとおりです。

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();  // 开始播放

ご覧のとおり、問題は原点に戻り、ビジネス コードに if 条件分岐構造が再び現れています。では、この問題をどうやって解決すればいいのでしょうか?

ファクトリ クラスの単純なファクトリを作成して、ファクトリ クラス オブジェクトを作成できます。新しい単純なファクトリ コードは次のとおりです。

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();  // 开始播放

ご覧のとおり、ファクトリ パターンを使用すると、構造は以前よりもはるかに複雑になります。インスタンスを作成するプロセスをコピーする場合にのみ、ファクトリ メソッド パターンを使用することをお勧めします。

抽象ファクトリ パターン

抽象ファクトリ パターンは特別なシナリオで使用され、めったに使用されません。ファクトリーメソッドパターンでは、特定の工場が特定の製品の生産を担当し、各工場が特定の製品に対応します。しかし場合によっては、単一の製品ではなく複数の製品オブジェクトを作成できるファクトリが必要になることがあります。

例を見てみましょう: ターゲットのコンピューター工場は、販売用のコンピューターの製造を担当しています。コンピューターはホスト、キーボード、モニター、マウスで構成されていることがわかっています。現在、ターゲット コンピューター シティでは、ロープロファイル、ミッドレンジ、ハイプロファイルの 3 種類のコンピューターのみを製造しています。さまざまな構成のコンピューターは、使用するコンピューターを使用します。さまざまなホスト ブランド、モニター ブランドなど。

現在含まれているホスト: Kirin ホスト、Thunder ホスト、Winter ホスト

現在含まれているキーボード: Rapoo、Logitech、Razer

現在含まれているモニター: aoc、hkc、 BenQ

現在、マウスには Logitech、Spirit Snake、Founder が含まれています。

コンピューターの最上位バージョンは、Kirin ホスト、Rapoo キーボード、AOC モニター、Logitech マウスで構成され、中位バージョンは範囲バージョンは次のもので構成されています...

ホストのコードは次のとおりです:

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;
    }
}

同様に、キーボード、モニター、およびマウスを作成するコードはここには掲載されません。

ここで、コンピューターを作成するためのインターフェイスを定義します。

interface ComputerFactory
{
    static function createHost ();
    static function createKeyboard ();
    static function createMonitor ();
    static function createMouse ();
}

次に、ローエンド、ミッドエンド、ハイエンドのコンピューターを作成するための 3 つの特定の工場を完成させます。

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();
    }
}

これで特定のコンピュータを作成できるようになりました

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();
    }
}

以上が単純なファクトリ、ファクトリ メソッド、および抽象ファクトリを 1 つの記事で理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。