创建型模式
1.简单工厂
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/dc5b8b47b927b0a4fb4b8710731e4e13.png)
from abc import abstractmethod, ABC
class WashMode(ABC):
@abstractmethod
def wash(self):
pass
class WashingPowder(WashMode):
def wash(self):
print("使用洗衣粉洗衣服")
class WashingLiquid(WashMode):
def wash(self):
print("使用洗衣液洗衣服")
class WashingBall(WashMode):
def wash(self):
print("使用洗衣凝珠洗衣服")
class SimpleFactory:
@staticmethod
def choose_mode(method):
if method == "powder":
return WashingPowder()
elif method == "liquid":
return WashingLiquid()
else:
return WashingBall()
if __name__ == '__main__':
sf = SimpleFactory()
powder = sf.choose_mode("powder")
powder.wash()
liquid = sf.choose_mode("liquid")
liquid.wash()
ball = sf.choose_mode("ball")
ball.wash()
```,
```py
使用洗衣粉洗衣服
使用洗衣液洗衣服
使用洗衣凝珠洗衣服
角色
优点
缺点
- 如果需要使用肥皂洗,工厂就需要添加一条生产线,需要修改工厂类代码(增加
elif
判断),违反了开闭原则
2.工厂
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/9d0d56cb7db4dde7757d4941f7ae971f.png)
from abc import abstractmethod, ABC
class WashMode(ABC):
@abstractmethod
def wash(self):
pass
class WashingPowder(WashMode):
def wash(self):
print("使用洗衣粉洗衣服")
class WashingLiquid(WashMode):
def wash(self):
print("使用洗衣液洗衣服")
class WashingBall(WashMode):
def wash(self):
print("使用洗衣凝珠洗衣服")
class WashFactory(ABC):
@abstractmethod
def wash_method(self):
pass
class LiquidWash(WashFactory):
def wash_method(self):
return WashingPowder()
class PowderWash(WashFactory):
def wash_method(self):
return WashingLiquid()
class BallWash(WashFactory):
def wash_method(self):
return WashingBall()
if __name__ == '__main__':
liquid = PowderWash()
lw = liquid.wash_method()
lw.wash()
powder = LiquidWash()
pw = powder.wash_method()
pw.wash()
ball = BallWash()
bw = ball.wash_method()
bw.wash()
使用洗衣液洗衣服
使用洗衣粉洗衣服
使用洗衣凝珠洗衣服
角色
- 1.抽象产品角色
- 2.产品角色
- 3.抽象工厂角色
- 4.工厂角色(数量和具体产品数量相等)
优点
- 每个具体产品都对应一个具体工厂,新增加一个产品,不需要修改工厂类代码
- 如果想用肥皂洗,只需要再开一个工厂,增加一个洗衣工即可,不会影响其他工厂的正常运转
- 隐藏了对象创建的实现细节
缺点
- 每增加一个具体产品类,就必须增加一个相应的具体工厂类,随着功能的扩展,类会变得越来越多,不易阅读
- 如果想使用多个产品,就必须初始化多个类,增加了复杂性,增加了内存开销
- 如果只想使用洗衣粉洗,初始化一个
WashingPowder
类,调用它的wash
方法即可 - 如果同时需要用洗衣液来洗一些衣服,此时就需要在创建一个
WashingLiquid
类,调用它的wash
方法
3.抽象工厂
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3e2f4fb83c747fae87b172c215c35d42.png)
from abc import abstractmethod, ABC
class AbstractFactory(ABC):
@abstractmethod
def wash_with_powder(self):
pass
@abstractmethod
def wash_with_liquid(self):
pass
@abstractmethod
def wash_with_ball(self):
pass
class LiBaiFactory(AbstractFactory):
def __init__(self):
print("欢迎来到立白工厂...")
def wash_with_powder(self):
return WashingPowder()
def wash_with_liquid(self):
return WashingLiquid()
def wash_with_ball(self):
return WashingBall()
class TaiZiFactory(AbstractFactory):
def __init__(self):
print("欢迎来到汰渍工厂...")
def wash_with_powder(self):
return WashingPowder()
def wash_with_liquid(self):
return WashingLiquid()
def wash_with_ball(self):
return WashingBall()
class WashMode(ABC):
@abstractmethod
def wash(self):
pass
class WashingPowder(WashMode):
def wash(self):
print("使用洗衣粉洗衣服")
class WashingLiquid(WashMode):
def wash(self):
print("使用洗衣液洗衣服")
class WashingBall(WashMode):
def wash(self):
print("使用洗衣凝珠洗衣服")
if __name__ == '__main__':
lb = LiBaiFactory()
lbp = lb.wash_with_powder()
lbp.wash()
lbp = lb.wash_with_liquid()
lbp.wash()
lbp = lb.wash_with_ball()
lbp.wash()
tz = TaiZiFactory()
tzp = tz.wash_with_powder()
tzp.wash()
欢迎来到立白工厂...
使用洗衣粉洗衣服
使用洗衣液洗衣服
使用洗衣凝珠洗衣服
欢迎来到汰渍工厂...
使用洗衣粉洗衣服
角色
- 1.抽象工厂角色
- 2.工厂角色(每个工厂都具备所有的产品)
- 3.抽象产品角色
- 4.产品角色
优点
- 抽象工厂方法模式引出了
产品族
和产品等级
结构概念,其目的是为了更加高效的生产同一个产品组产品
产品族
:可以理解为具体的工厂产品等级
:可以理解为具体工厂对象中的方法- 当一个
产品族
中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象 - 比如工厂模式下存在的问题:想使用不同方式洗衣,如果对工厂没有要求的话,只需要实例化一个工厂对象即可满足
- 增加新的
产品族
很方便,无须修改已有系统,符合“开闭原则”。
- 即增加一个新的工厂很方便,只需要满足三种方式的洗衣模式即可,不会影响原有工厂正常运行
缺点
- 如果想要增加一个产品等级,就会打破开闭原则
- 比如,想要增加一个产品(通过肥皂)洗衣服,此时就需要修改抽象产品类,同时需要修改具体产品类,还需要修改抽象工厂类和具体工厂类
- 所以抽象工厂模式下,必须要满足产品等级的固定性,比如,如果将生物看作一个产品,那么作为产品等级的性别,非男即女,不会出现增加或减少