最近写了一些python的代码之后发现一个问题,之前学过的设计模式,包括面向对象的一下思想都没用用上,正好在网上找到了一个包含很多python设计模式的项目(在结尾引用中有)通过python把这些设计模式都实现一遍,也可以作为使用的模板
抽象工厂
定义
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
模式例子
抽象工厂模式中有工厂和产品簇的概念。而一簇的产品都是成套出现的。比如现在要给每个士兵发一套武器,包括枪和子弹。步枪和步枪子弹,手枪和手枪子弹。生产步枪的工厂就是步枪工厂,而生产手枪的工厂就是手枪工厂。步枪工厂和手枪工厂都是工厂,这就是一种抽象工厂的例子
场景
例如windows的bottons和unix的bottons
UML
以士兵的例子为例uml如下
下面是plantuml的编码
plantuml可以通过编码生产各种诸如类图,流程图这样的图标,而不用通过手动的修改。
@startuml
skinparam monochrome true
"AbstractFactory" <|-- "RifleFactory"
"AbstractFactory" <|-- "HandgunFactory"
"AbstractGun" <|-- Rifle
"AbstractGun" <|-- Handgun
"AbstractBullet" <|-- "RfileBullet"
"AbstractBullet" <|-- "HandgunBullet"
"RifleFactory" ..> Rifle
"RifleFactory" ..> "RfileBullet"
"HandgunFactory" ..> Handgun
"HandgunFactory" ..> "HandgunBullet"
@enduml
python 代码实现
用户类
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
"""Implementation of the abstract factory pattern"""
import abc
import random
class Solider(object):
def __init__(self, gun, buttle):
self.gun = gun
self.buttle = buttle
def fire(self):
self.gun.pong()
self.buttle.pa()
抽象工厂
class Gunfactory(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def get_gun(self):
pass
@abc.abstractmethod
def get_bullet(self):
pass
抽象产品
class Gun(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def pong(self):
pass
class Bullet(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def pa(self):
pass
实际产品
class Rifle(Gun):
def pong(self):
print "Rifle fire,pong!"
class Handgun(Gun):
def pong(self):
print "Handgun fire,pong,pong,pong"
class RifleBullet(Bullet):
def pa(self):
print "Rifle buttle,pa!"
class HandgunBullet(Bullet):
def pa(self):
print "Handgun buttle,pa,pa,pa"
实际工厂
class RifleFactory(Gunfactory):
def get_gun(self):
return Rifle()
def get_bullet(self):
return RifleBullet()
class HandgunFactory(object):
def get_gun(self):
return Handgun()
def get_bullet(self):
return HandgunBullet()
调用
if __name__ == "__main__":
rifle_factory = RifleFactory()
handgun_factory = HandgunFactory()
factories = [rifle_factory, handgun_factory]
for i in range(4):
factory = random.choice(factories)
gun = factory.get_gun()
bullet = factory.get_bullet()
solider = Solider(gun, bullet)
solider.fire()
print("=" * 20)
### OUTPUT ###
# Rifle fire,pong!
# Rifle buttle,pa!
# ====================
# Handgun fire,pong,pong,pong
# Handgun buttle,pa,pa,pa
# ====================
# Handgun fire,pong,pong,pong
# Handgun buttle,pa,pa,pa
# ====================
# Rifle fire,pong!
# Rifle buttle,pa!
# ====================
抽象工厂模式与工厂模式与简单工厂模式的关系
当抽象工厂模式中每一个具体工厂类只创建一个产品对象(工厂只造枪),也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂(只有步枪工厂)来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。
抽象工厂的优缺点
优点
-
客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。 所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
-
另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点
- 在添加新的产品对象比较困难,因为要对所有的工厂都添加类似产品 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。
注:
所有的设计模式相关的代码都在这里这也是从别的地方看到的,我自己fork了一份,但是里面有些地方不是很准确,所有我自己修改了一份