当前位置: 首页 > news >正文

设计模式——工厂模式学习总结

假设现在一个场景:
某物流公司,当前有以下业务:汽车运输和轮船运输。客户可以选择任一运输方式进行运输。

此时,应该如何使用代码将这个现实业务进行抽象实现?

在没有学习工厂模式前,我是这样想的,分别写个物流公司的类,然后它依赖汽车类和轮船类,让汽车类和轮船都实现运输接口,然后让用户传递一个参数,参数将决定给用户返回汽车或者轮船,这样就实现了。
在这里插入图片描述

代码如下:

from abc import ABC,abstractmethod

class Logistics:
    def __init__(self,transport):
        self.transport_map = {
            "car":Car(),
            "ship":Ship()
        }
        self.transport = self.transport_map[transport]

    def deliver(self):
        return self.transport.deliver()

class Delivery(ABC):
    @abstractmethod
    def deliver(self):
        pass

class Car(Delivery):
    def deliver(self):
        return "A car has delivered."

class Ship(Delivery):
    def deliver(self):
        return "A ship has deliverd"

def client(transport):
    print(Logistics(transport).deliver())

if __name__ == "__main__":
    client("car")
    client("ship")

执行结果如下:
在这里插入图片描述

这样写是能够满足这篇文章最初的要求的,但是随着公司的扩展,业务又支持火车运输了,此时,应该怎么写代码?一定是要修改Logistic类的对吗?每增加一种运输方式,我们就要修改一次Logistics类的代码,对吗?

此时就存在一个问题,我们违背了SOLID原则中的开闭原则:对修改关闭,对扩展开放。我们这里只是写了一个很简单的场景,实际的场景中,一旦违背这个原则,可能会引入很多问题,甚至会威胁软件本身。比如,我们要将一个系统提供给用户,让用户可以自定义增加运输类型,让用户修改代码,或者让用户写的代码通过我们提供的方式植入到原有的代码中,都可能会带来安全隐患。

此时,我们可以通过工厂模式,让父类决定对外的功能,让子类决定创建的具体的对外服务的对象,则可以在不修改代码的情况下,进行扩展。

比如这个在这个题目中,我们让物流公司(后面称为总公司)下面创建两个子公司:陆路物流公司、海洋物流公司。物流总公司定义一个创建运输工具的接口,让子公司通过实现这个接口来创建自己的运输工具。物流总公司定义“运输”的方法,所有它的子公司都将支持“运输”。至于“运输”如何实现,可以让子公司来实现,也可以让运输工具来实现,都是可以的,但是出于对以后扩展性的考虑,可以让运输工具来实现。因为,比如让陆路物流公司实现“运输”方法,那意味着陆路公司只有1种“运输”方法,那么万一这个陆路物流公司后面又支持了火车运输怎么办?而如果让汽车这个运输工具来实现运输方法,则当以后陆路物流公司支持火车运输时,火车可以扩展出自己的运输方法。
在这里插入图片描述
代码如下:

from abc import ABC,abstractmethod

class Logistics(ABC):

    @abstractmethod
    def createTransport(self):
        pass

    def planDelivery(self):
        transport = self.createTransport()
        result = transport.deliver()
        return result

class Transport(ABC):
    @abstractmethod
    def deliver(self):
        pass

class RoadLogistics(Logistics):
    def createTransport(self):
        return Car()

class SeaLogistics(Logistics):
    def createTransport(self):
        return Ship()

class Car(Transport):
    def deliver(self):
        return "A new car has delivered."

class Ship(Transport):
    def deliver(self):
        return "A new ship has delivered."

def client(logistic):
    print(logistic.planDelivery())

if __name__ == "__main__":
    client(RoadLogistics())
    client(SeaLogistics())

执行结果如下:
在这里插入图片描述

总结:当不同子类有一些差别时,我们可以把创建对象的工作让子类来完成,此时就可以用工厂模式。

相关文章:

  • 企业数据安全---数据分级
  • 【深度学习与大模型基础】第9章-条件概率以及条件概率的链式法则
  • Linux xorg-server 解析(二)- 如何调试 xorg-server
  • asm汇编字符串操作
  • 【NumPy科学计算:高性能数组操作核心指南】
  • a sort.py demo
  • 2024年React最新高频面试题及核心考点解析,涵盖基础、进阶和新特性,助你高效备战
  • Vue 接口请求 Nginx配置实时压缩 速度起飞
  • LVGL Arc控件和Roller控件详解
  • 【Java多线程】告别线程混乱!深度解析Java多线程4大实现方式(附实战案例)
  • Spring Boot 3.4.3 和 Spring Security 6.4.2 结合 JWT 实现用户登录
  • 青少年编程考试 CCF GESP图形化编程 四级认证真题 2025年3月
  • 基于SpringBoot的家教管理系统【附源码】
  • 拖拽实现3
  • Docker 安装redis
  • Docker--利用dockerfile搭建mysql主从集群和redis集群
  • 在MATLAB中使用MPI进行并行编程
  • 特殊定制版,太给力了!
  • MySQL进阶-存储引擎索引
  • 设计模式 Day 9:命令模式(Command Pattern)完整讲解与实战应用
  • 丹东网站推广/日照seo优化
  • 成都眉山网站建设/防疫测温健康码核验一体机
  • 怎么做网站搜索引擎/百度风云排行榜
  • 做设计的公司的网站/购买模板建站
  • 网站是用什么程序做的/百度地址如何设置门店地址
  • 做彩投网站犯法吗/怎么样建一个网站