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

【再谈设计模式】工厂模式~制造者的艺术

一、引言

        在软件工程的广阔领域中,设计模式充当着程序员解决问题的宝典。其中,“工厂模式”作为一种关键的创建型模式,不仅简化了对象的实例化流程,还增强了代码的扩展性和复用性。探索工厂模式的核心思想、应用场景及其实现细节。

二、工厂模式定义与描述

        工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪种类。工厂方法使一个类的实例化延迟到子类。

三、抽象背景

        在面向对象编程中,随着项目规模的扩大,对象的创建变得越来越复杂。直接实例化对象可能导致代码耦合度高,不易维护和扩展。工厂模式通过提供一个统一的创建对象的接口,将对象的创建逻辑封装在一个或多个工厂类中,从而解决了这一问题。

四、适用场景与现实问题解决

工厂模式适用于以下场景

        当对象的创建逻辑复杂,包含许多条件判断时。
        当系统需要创建的产品对象属于同一族时。
        当期望通过配置文件来控制实例化对象时。

现实问题:

        当你的系统需要依赖于一系列的对象,而这些对象的创建逻辑较为复杂,或者创建逻辑可能随时间发生变化,直接实例化这些对象会导致代码难以维护和扩展。工厂模式通过将对象的创建逻辑封装在工厂类中,实现了对象创建和使用分离,提高了代码的复用性和可扩展性。

讲故事:

场景设定

        想象一下,你是一位美食博主,最近迷上了一款名为“汉堡大作战”的游戏。游戏的目标是经营自己的汉堡店,吸引顾客,赚取金币。但是,经营汉堡店可不容易,尤其是当你得同时应对各种口味刁钻的顾客时。不过,游戏开发者们很贴心地为你准备了一个秘密武器——“汉堡工厂”。

引入工厂模式

        你开始了解到,汉堡工厂是个神奇的地方,它可以根据你的需求,快速生产出各种各样的汉堡。比如,有经典牛肉堡、鸡肉堡、素食堡……你只需要告诉工厂你想要什么,剩下的就交给它搞定。

        这就是工厂模式的魅力所在!它就像你的汉堡工厂,帮你遮风挡雨,让你专注于对外销售,而不用操心里面那些复杂的制作流程。在代码的世界里,工厂模式就是那个帮你生产对象的工厂,你只要调用一下,就可以拿到你需要的东西啦!

故事发展

        一天,你迎来了第一个挑战,一场名为“汉堡节”的盛会即将来临,你必须在短时间内准备大量的汉堡。幸好,有了汉堡工厂的帮助,你可以轻松应对。

        你向工厂发出了指令:“给我来10个牛肉堡!”工厂迅速响应,生产出10个美味的牛肉堡。接着,“再来20个鸡肉堡!”工厂再次展示其高效,20个鸡肉堡新鲜出炉。

        就这样,你一边指挥着工厂,一边享受着顾客们的赞誉。汉堡节圆满结束,你也收获了满满一袋的金币。

工厂模式如何运作

        工厂模式背后的理念很简单,就是把对象的实例化过程封装起来,隐藏创建对象的复杂逻辑,只提供一个创建对象的方法。在我们的汉堡故事里,这个方法就像是一个按钮,你按下它,就能得到你想要的汉堡。

为什么工厂模式如此重要?

        灵活性:你可以随时添加新的汉堡类型,只需扩展原有的工厂,不需要修改调用者的代码。

        隔离性:调用者只需要关注“我要什么”,不用管“怎么得到”。

        易维护性:如果汉堡的制作流程改变了,你只需要修改工厂里的代码,其他地方都不用动。

        通过这个汉堡故事,我们看到了工厂模式在实际应用中的威力。它就像那位背后的英雄,默默地支撑着你的汉堡店,让你的业务运营更为顺畅。无论是游戏中的汉堡工厂,还是生活中的任何场景,工厂模式都是一把解决对象创建难题的利器。

五、工厂模式的初衷与问题解决
        

        工厂模式的初衷在于降低代码间的耦合度,使代码更加模块化,易于维护和扩展。通过抽象和继承,可以灵活地添加新的产品类,而无需改动已有的客户端代码。

六、实现与编码示例

Java 示例:

public interface Product {
    void use();
}

public class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductA");
    }
}

public class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductB");
    }
}

public interface Factory {
    Product create();
}

public class ConcreteFactoryA implements Factory {
    @Override
    public Product create() {
        return new ConcreteProductA();
    }
}

public class ConcreteFactoryB implements Factory {
    @Override
    public Product create() {
        return new ConcreteProductB();
    }
}


Python 示例:

class Product:
    def use(self):
        pass

class ConcreteProductA(Product):
    def use(self):
        print("Using ConcreteProductA")

class ConcreteProductB(Product):
    def use(self):
        print("Using ConcreteProductB")

class Factory:
    def create(self):
        pass

class ConcreteFactoryA(Factory):
    def create(self):
        return ConcreteProductA()

class ConcreteFactoryB(Factory):
    def create(self):
        return ConcreteProductB()

C++ 示例:

#include <iostream>

class Product {
public:
    virtual void use() = 0;
};

class ConcreteProductA : public Product {
public:
    void use() override {
        std::cout << "Using ConcreteProductA\n";
    }
};

class ConcreteProductB : public Product {
public:
    void use() override {
        std::cout << "Using ConcreteProductB\n";
    }
};

class Factory {
public:
    virtual Product* create() = 0;
};

class ConcreteFactoryA : public Factory {
public:
    Product* create() override {
        return new ConcreteProductA();
    }
};

class ConcreteFactoryB : public Factory {
public:
    Product* create() override {
        return new ConcreteProductB();
    }
};

Go 示例:

package main

import (
    "fmt"
)

type Product interface {
    Use()
}

type ConcreteProductA struct{}

func (a *ConcreteProductA) Use() {
    fmt.Println("Using ConcreteProductA")
}

type ConcreteProductB struct{}

func (b *ConcreteProductB) Use() {
    fmt.Println("Using ConcreteProductB")
}

type Factory interface {
    Create() Product
}

type ConcreteFactoryA struct{}

func (f *ConcreteFactoryA) Create() Product {
    return &ConcreteProductA{}
}

type ConcreteFactoryB struct{}

func (f *ConcreteFactoryB) Create() Product {
    return &ConcreteProductB{}
}

七、工厂模式的优缺点

优点:

        提高了系统的灵活性和可扩展性。
        封装了产品的创建逻辑,避免了在客户端代码中硬编码产品类。
        符合单一职责原则和开闭原则。
缺点:

        增加了系统复杂度,尤其是当工厂类数量庞大时。
        难以满足复杂的业务逻辑,如果创建逻辑过于复杂,可能需要进一步细化工厂。

八、工厂模式的升级版

        工厂模式的升级版通常是抽象工厂模式(Abstract Factory),它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。这对于需要创建具有相同主题的对象集合的情况特别有用。

        工厂模式作为设计模式的基础之一,其极高的适用性和灵活性使其成为现代软件设计中不可或缺的一部分。通过上述代码实现,我们可以清晰地看到工厂模式如何简化对象创建的复杂性,为软件工程带来更高的效率和可维护性。


http://www.kler.cn/news/364532.html

相关文章:

  • 初学者指南:软件测试
  • 数据结构——队列和栈
  • RHCSA笔记三
  • C#学习笔记(五)
  • 链路分析对性能测试的意义
  • XML\XXE漏洞基本原理
  • tomcat基本配置
  • 高性能数据分析利器DuckDB在Python中的使用
  • Web页面测试方法「详细介绍」
  • 【赵渝强老师】Oracle的控制文件与归档日志文件
  • python:pygame, pyOpenGL 示例:旋转的八面体
  • JAVA 单例模式实验(头歌)
  • 【ROS GitHub使用】
  • ​8.13TB高清卫星影像更新(WGS84坐标投影)
  • 简单三步完成 Telegram 生态的 Web3 冷启动
  • rsync算法原理
  • Vue3 + Element Plus 封装文本超出长度显示省略号,鼠标移上悬浮展示全部内容的组件
  • 关于建造者模式(Builder Pattern)
  • 写出Windows操作系统内核的程序员,70多岁,还去办公室敲代码
  • Scala trait
  • 912.排序数组(计数排序)
  • QML列表视图 ListView的使用
  • Jenkins + GitLab + Docker实现自动化部署(Java项目)
  • 深入了解 Pandas 中的数据:Series 和 DataFrame 的使用指南
  • 借助栈逆置单链表
  • 基于YOLOv8深度学习的高密度人脸智能检测与统计系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测