zoukankan      html  css  js  c++  java
  • 【设计模式】抽象工厂模式

    抽象工厂模式

    简介

    logo

    抽象工厂模式,其抽象程度更高,每一个具体工厂可以生产一组相关的具体产品对象。

    抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

    结构

    uml

    实现

    实现方式:

    • 以不同的产品类型与产品变体为维度绘制矩阵。
    • 为所有产品声明抽象产品接口。然后让所有具体产品类实现这些接口。
    • 声明抽象工厂接口,并且在接口中为所有抽象产品提供一组构建方法。
    • 为每种产品变体实现一个具体工厂类。
    • 在应用程序中开发初始化代码。该代码根据应用程序配置或当前环境,对特定具体工厂类进行初始化。然后将该工厂对象传递给所有需要创建产品的类。
    • 找出代码中所有对产品构造函数的直接调用,将其替换为对工厂对象中相应构建方法的调用。
    #include <iostream>
    
    
    class AbstractProductA {
    public:
        virtual ~AbstractProductA() {};
        virtual std::string usefulFuncA() const = 0;
    };
    
    class ConcreteProductA1: public AbstractProductA {
    public:
        std::string usefulFuncA() const override {
            return "The result of the product A1.";
        }
    };
    
    class ConcreteProductA2: public AbstractProductA {
    public:
        std::string usefulFuncA() const override {
            return "The result of the product A2.";
        }
    };
    
    class AbstractProductB {
    public:
        virtual ~AbstractProductB() {};
        virtual std::string usefulFuncB() const = 0;
        virtual std::string anotherUsefulFuncB(const AbstractProductA& collaborator) const = 0;
    };
    
    class ConcreteProductB1: public AbstractProductB {
    public:
        std::string usefulFuncB() const override {
            return "The result of the product B1.";
        }
        std::string anotherUsefulFuncB(const AbstractProductA& collaborator) const override {
            const std::string result = collaborator.usefulFuncA();
            return "The result of the B1 collaborating with ( " + result + " )";
        }
    };
    
    class ConcreteProductB2: public AbstractProductB {
    public:
        std::string usefulFuncB() const override {
            return "The result of the product B2.";
        }
        std::string anotherUsefulFuncB(const AbstractProductA& collaborator) const override {
            const std::string result = collaborator.usefulFuncA();
            return "The result of the B2 collaborating with ( " + result + " )";
        }
    };
    
    class AbstractFactory {
    public:
        virtual AbstractProductA* CreateProductA() const  = 0;
        virtual AbstractProductB* CreateProductB() const  = 0;
    };
    
    class ConcreteFactory1 : public AbstractFactory {
    public:
        AbstractProductA* CreateProductA() const override {
            return new ConcreteProductA1();
        }
        AbstractProductB* CreateProductB() const override {
            return new ConcreteProductB1();
        }
    };
    
    class ConcreteFactory2 : public AbstractFactory {
    public:
        AbstractProductA* CreateProductA() const override {
            return new ConcreteProductA2();
        }
        AbstractProductB* CreateProductB() const override {
            return new ConcreteProductB2();
        }
    };
    
    void ClientCode(const AbstractFactory& factory) {
        const AbstractProductA* proA = factory.CreateProductA();
        const AbstractProductB* proB = factory.CreateProductB();
        std::cout << proB->usefulFuncB() << std::endl;
        std::cout << proB->anotherUsefulFuncB(*proA) << std::endl;
        delete proA;
        delete proB;
    }
    
    int main(int argc, char* argv[]) {
        std::cout << "Client: Testing client code with the first factory type:
    ";
        ConcreteFactory1 *f1 = new ConcreteFactory1();
        ClientCode(*f1);
        delete f1;
        std::cout << std::endl;
        std::cout << "Client: Testing the same client code with the second factory type:
    ";
        ConcreteFactory2 *f2 = new ConcreteFactory2();
        ClientCode(*f2);
        delete f2;
        return 0;
    }
    
    from __future__ import annotations
    from abc import ABC, abstractmethod
    
    
    class AbstractProductA(ABC):
        """
        """
    
        @abstractmethod
        def useful_function_a(self) -> str:
            pass
    
    
    class ConcreteProductA1(AbstractProductA):
        """
        """
        def useful_function_a(self) -> str:
            return "The result of the product A1."
    
    
    class ConcreteProductA2(AbstractProductA):
        """
        """
        def useful_function_a(self) -> str:
            return "The result of the product A2."
    
    
    class AbstractProductB(ABC):
        """
        """
        @abstractmethod
        def useful_function_b(self) -> None:
            """
            Product B is able to do its own thing...
            """
            pass
    
        @abstractmethod
        def another_useful_function_b(self, collaborator: AbstractProductA) -> None:
            """
            """
            pass
    
    
    class ConcreteProductB1(AbstractProductB):
        def useful_function_b(self) -> str:
            return "The result of the product B1."
    
        def another_useful_function_b(self, collaborator: AbstractProductA) -> str:
            result = collaborator.useful_function_a()
            return f"The result of the B1 collaborating with the ({result})"
    
    
    class ConcreteProductB2(AbstractProductB):
        def useful_function_b(self) -> str:
            return "The result of the product B2."
    
        def another_useful_function_b(self, collaborator: AbstractProductA):
            result = collaborator.useful_function_a()
            return f"The result of the B2 collaborating with the ({result})"
    
    
    class AbstractFactory(ABC):
        """
        """
        @abstractmethod
        def create_product_a(self) -> AbstractProductA:
            pass
    
        @abstractmethod
        def create_product_b(self) -> AbstractProductB:
            pass
    
    
    class ConcreteFactory1(AbstractFactory):
        """
        """
    
        def create_product_a(self) -> ConcreteProductA1:
            return ConcreteProductA1()
    
        def create_product_b(self) -> ConcreteProductB1:
            return ConcreteProductB1()
    
    
    class ConcreteFactory2(AbstractFactory):
        """
        """
    
        def create_product_a(self) -> ConcreteProductA2:
            return ConcreteProductA2()
    
        def create_product_b(self) -> ConcreteProductB2:
            return ConcreteProductB2()
    
    
    def client_code(factory: AbstractFactory) -> None:
        """
        """
        product_a = factory.create_product_a()
        product_b = factory.create_product_b()
    
        print(f"{product_b.useful_function_b()}")
        print(f"{product_b.another_useful_function_b(product_a)}", end="")
    
    
    if __name__ == "__main__":
        print("Client: Testing client code with the first factory type:")
        client_code(ConcreteFactory1())
    
        print("
    ")
    
        print("Client: Testing the same client code with the second factory type:")
        client_code(ConcreteFactory2())
    

    实例

    问题描述

    同学们想要进行户外运动,他们可以选择打篮球、踢足球或者玩排球。它们分别有篮球保管室、足球保管室和排球保管室管理,但是不想弄转脏自己的衣服,还需要球衣,分别对应着不同球类,只需要去相应的保管室就能拿到相应的球和球衣。

    问题解答

    // Example.cpp
    
    #include <iostream>
    
    class AbstractBall {
    public:
        virtual ~AbstractBall() {}
        virtual void play() const = 0;
    };
    
    class Basketball: public AbstractBall {
    public:
        Basketball() {
            play();
        }
        void play() const override {
            std::cout << "play basketball." << std::endl;
        }
    };
    
    class Football: public AbstractBall {
    public:
        Football() {
            play();
        }
        void play() const override {
            std::cout << "play football." << std::endl;
        }
    };
    
    class AbstractShirt {
    public:
        virtual ~AbstractShirt() {}
        virtual void wear() const = 0;
    };
    
    class BasketballShirt: public AbstractShirt {
    public:
        BasketballShirt() {
            wear();
        }
        void wear() const override {
            std::cout << "wear basketball shirt." << std::endl;
        }
    };
    
    class FootballShirt: public AbstractShirt {
    public:
        FootballShirt() {
            wear();
        }
        void wear() const override {
            std::cout << "wear football shirt." << std::endl;
        }
    };
    
    class AbstractFactory {
    public:
        virtual AbstractBall* getBall() const = 0;
        virtual AbstractShirt* getShirt() const = 0;
    };
    
    class BasketballFactory: public AbstractFactory {
    public:
        AbstractBall* getBall() const override {
            std::cout << "get basketball." << std::endl;
            return new Basketball();
        }
        AbstractShirt* getShirt() const override {
            std::cout << "get basketball shirt." << std::endl;
            return new BasketballShirt();
        }
    };
    
    class FootballFactory: public AbstractFactory {
    public:
        AbstractBall* getBall() const override {
            std::cout << "get football." << std::endl;
            return new Football();
        }
        AbstractShirt* getShirt() const override {
            std::cout << "get football shirt." << std::endl;
            return new FootballShirt();
        }
    };
    
    
    int main(int argc, char * argv[]) {
        AbstractFactory* fac = nullptr;
        AbstractBall* ball = nullptr;
        AbstractShirt* shirt = nullptr;
    
        fac = new BasketballFactory();
        ball = fac->getBall();
        shirt = fac->getShirt();
        std::cout << std::endl;
    
        fac = new FootballFactory();
        ball = fac->getBall();
        shirt = fac->getShirt();
        std::cout << std::endl;
    
        delete fac;
        delete ball;
        delete shirt;
    
        return 0;
    }
    

    总结

    优点

    • 新加入产品系列时,无需改动原有系统,增强了系统的可拓展性,符合开闭原则
    • 你可以将产品生成代码抽取到同一位置, 使得代码易于维护,符合单一职责原则

    缺点

    • 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。

    场景

    • 如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂模式。
    • 如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。

    与其他模式的关系

    • 在许多设计工作的初期都会使用工厂方法模式(较为简单,而且方便通过子类进行定制),随后演变为使用抽象工厂模式原型模式建造者模式
    • 抽象工厂模式通常基于一组工厂方法,但你也可以使用原型模式来生成这些类的方法。
    • 建造者模式重点关注如何分步生成复杂对象。抽象工厂模式专门用于生产一系列相关对象。抽象工厂会马上返回产品,建造者则允许你在获取产品前执行一些额外构造步骤。
    • 你可以将抽象工厂模式桥接模式搭配使用。如果由桥接定义的抽象只能与特定实现合作,这一模式搭配就非常有用。在这种情况下,抽象工厂可以对这些关系进行封装,并且对客户端代码隐藏其复杂性。
    • 抽象工厂模式建造者模式原型模式都可以用单例模式来实现。
  • 相关阅读:
    细说google,baidu引擎收录习惯
    考研机试 11.二叉树遍历
    考研机试 18.特殊乘法
    考研机试 19.今年的第几天
    考研机试 20.完数VS盈数
    考研机试 12.玛雅人的密码
    考研机试 10.球的半径和体积
    考研机试 17.n的阶乘
    考研机试 15.abc
    考研机试 9.成绩排序
  • 原文地址:https://www.cnblogs.com/parzulpan/p/13546465.html
Copyright © 2011-2022 走看看