设计模式学习

设计模式:抽象工厂模式

2022-01-25  本文已影响0人  狄仁杰666

前言

来啦老铁!

笔者正在学习常见的设计模式,且将设计模式系列学习文章归入 “设计模式学习” 专题,赶快关注专题一起学习吧!

今天我们先来学习:

备注:笔者的学习资料大部分来源于:菜鸟教程

学习路径

  1. 抽象工厂模式简介;
  2. 抽象工厂模式代码实现;
  3. 抽象工厂模式优缺点分析;
  4. 抽象工厂模式使用场景介绍;

1. 抽象工厂模式简介;

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。

我个人的理解是,抽象工厂模式是一种特殊的工厂模式,抽不抽象都属于工厂模式。该工厂不是用来创建具体的东西的,而是用来创建其他工厂的,举个可能不太恰当的例子,类似于之前马云说的一句话:阿里巴巴就是要创建更多的京东~

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

主要解决:主要解决接口选择的问题。

何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

如何解决:在一个产品族里面,定义多个产品。

关键代码:在一个工厂里聚合多个同类产品。

2. 抽象工厂模式代码实现;

我另外想一个案例,例如:我们对公司的在线课程按抽象工厂模式做一个练习,在线课程分为课程基本信息、在不同平台上的类似操作(例如推送课程消息、播放课程视频等),这里头我们可以声明一个抽象工厂,用于创建 2 个工厂:课程信息工厂、课程平台工厂;

先上代码结构:


代码结构
  1. 编写课程基类:course.py
class Course:
    def __init__(self, course_name, course_prize):
        self.course_name = course_name
        self.course_prize = course_prize

    def get_course_name(self):
        print("get_course_name:", self.course_name)
        return self.course_name

    def get_course_prize(self):
        print("get_course_prize:", self.course_prize)
        return self.course_prize

  1. 编写课程平台基类:provider.py
class Provider:
    def __init__(self, message, play):
        self.message = message
        self.play = play

    def push_message(self):
        print("推送消息:", self.message)

    def play_video(self):
        if not self.play:
            return
        print("开始播放视频。。。")

  1. 编写具体课程类:
from course import Course


class JavaCourse(Course):
    def __init__(self):
        super().__init__("Java 课程", "¥1280")

from course import Course


class PythonCourse(Course):
    def __init__(self):
        super().__init__("Python 课程", "¥1999")

  1. 编写课程工厂类:
from javaCourse import JavaCourse
from pythonCourse import PythonCourse


class CourseFactory:
    def __init__(self):
        pass

    @staticmethod
    def get_course(course_name):
        if not course_name:
            return None
        if course_name.lower() == "java":
            return JavaCourse()
        if course_name.lower() == "python":
            return PythonCourse()

  1. 编写平台基类:
class Provider:
    def __init__(self, message, play):
        self.message = message
        self.play = play

    def push_message(self):
        print("推送消息:", self.message)

    def play_video(self):
        if not self.play:
            return
        print("开始播放视频。。。")

  1. 编写具体平台类:
from provider import Provider


class WangyiProvider(Provider):
    def __init__(self):
        super().__init__("快来网易学习啦~", True)

from provider import Provider


class BaiduProvider(Provider):
    def __init__(self):
        super().__init__("快来百度学习啦~", True)

  1. 编写平台工厂类:
from wangyiProvider import WangyiProvider
from baiduProvider import BaiduProvider


class ProviderFactory:
    def __init__(self):
        pass

    @staticmethod
    def get_provider(provider_name):
        if not provider_name:
            return None
        if provider_name.lower() == "wangyi":
            return WangyiProvider()
        if provider_name.lower() == "baidu":
            return BaiduProvider()

  1. 编写工厂接口类:
from courseFactory import CourseFactory
from providerFactory import ProviderFactory


class FactoryProducer:
    def __init__(self):
        pass

    @staticmethod
    def get_factory(factory_name):
        if not factory_name:
            return None
        if factory_name.lower() == "course":
            return CourseFactory()
        if factory_name.lower() == "provider":
            return ProviderFactory()

  1. 编写测试;
from factoryProducer import FactoryProducer


def test():
    course_factory = FactoryProducer().get_factory("course")
    java_course = course_factory.get_course("java")
    java_course.get_course_name()
    java_course.get_course_prize()
    python_course = course_factory.get_course("python")
    python_course.get_course_name()
    python_course.get_course_prize()

    print("---------------分割线-----------------")

    provider_factory = FactoryProducer().get_factory("provider")
    wangyi = provider_factory.get_provider("wangyi")
    wangyi.push_message()
    wangyi.play_video()
    baidu = provider_factory.get_provider("baidu")
    baidu.push_message()
    baidu.play_video()


if __name__ == '__main__':
    test()

  1. 测试:


    测试

以上就是抽象工厂模式的一个练习,笔者也不是很熟练,如有错误,还请帮忙指正,万分感谢,我也将不断探索、使用,以达熟练程度~

3. 抽象工厂模式优缺点分析;

  1. 优点:

抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

  1. 缺点:

产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

4. 抽象工厂模式使用场景介绍;

当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。

(按照上述,感觉我的例子也可以用 2 个独立的工厂来创建,😭,你觉得呢?)

使用场景:
1、QQ 换皮肤,一整套一起换;
2、生成不同操作系统的程序;

如果本文对您有帮助,麻烦点赞、关注!

谢谢!

上一篇 下一篇

猜你喜欢

热点阅读