前言
来啦老铁!
笔者正在学习常见的设计模式,且将设计模式系列学习文章归入 “设计模式学习” 专题,赶快关注专题一起学习吧!
今天我们先来学习:
-
抽象工厂模式
备注:笔者的学习资料大部分来源于:菜鸟教程;
学习路径
- 抽象工厂模式简介;
- 抽象工厂模式代码实现;
- 抽象工厂模式优缺点分析;
- 抽象工厂模式使用场景介绍;
1. 抽象工厂模式简介;
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。
我个人的理解是,抽象工厂模式是一种特殊的工厂模式,抽不抽象都属于工厂模式。该工厂不是用来创建具体的东西的,而是用来创建其他工厂的,举个可能不太恰当的例子,类似于之前马云说的一句话:阿里巴巴就是要创建更多的京东~
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
2. 抽象工厂模式代码实现;
我另外想一个案例,例如:我们对公司的在线课程按抽象工厂模式做一个练习,在线课程分为课程基本信息、在不同平台上的类似操作(例如推送课程消息、播放课程视频等),这里头我们可以声明一个抽象工厂,用于创建 2 个工厂:课程信息工厂、课程平台工厂;
- 我们可以从课程信息工厂创建课程实例来获课程基础取信息;
- 我们可以从课程平台工厂创建平台工厂来对不同平台执行一些操作,如推送课程消息、播放课程视频等;
先上代码结构:
代码结构
- 编写课程基类: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
- 编写课程平台基类: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("开始播放视频。。。")
- 编写具体课程类:
- java: javaCourse.py
from course import Course
class JavaCourse(Course):
def __init__(self):
super().__init__("Java 课程", "¥1280")
- python: pythonCourse.py
from course import Course
class PythonCourse(Course):
def __init__(self):
super().__init__("Python 课程", "¥1999")
- 编写课程工厂类:
- courseFactory.py
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()
- 编写平台基类:
- 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("开始播放视频。。。")
- 编写具体平台类:
- wangyiProvider.py
from provider import Provider
class WangyiProvider(Provider):
def __init__(self):
super().__init__("快来网易学习啦~", True)
- baiduProvider.py
from provider import Provider
class BaiduProvider(Provider):
def __init__(self):
super().__init__("快来百度学习啦~", True)
- 编写平台工厂类:
- providerFactory.py
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()
- 编写工厂接口类:
- factoryProducer.py
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()
- 编写测试;
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()
-
测试:
测试
以上就是抽象工厂模式的一个练习,笔者也不是很熟练,如有错误,还请帮忙指正,万分感谢,我也将不断探索、使用,以达熟练程度~
3. 抽象工厂模式优缺点分析;
- 优点:
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
- 缺点:
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
4. 抽象工厂模式使用场景介绍;
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。
(按照上述,感觉我的例子也可以用 2 个独立的工厂来创建,😭,你觉得呢?)
使用场景:
1、QQ 换皮肤,一整套一起换;
2、生成不同操作系统的程序;
如果本文对您有帮助,麻烦点赞、关注!
谢谢!
网友评论