坦克大战-抽象工厂实现

博客以实例讲解抽象工厂设计模式,它像零部件加工场,能创建一系列对象并控制产品风格。与创建型模式对比,创建型模式强调创建步骤,抽象工厂更注重产品系列。还以坦克大战为例,将发射和速度作为抽象工厂的系列产品,并给出Java、C#、JS、C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概要

2.内容

目录:《一个实例讲完23种设计模式》

当前:抽象工厂

说明:抽象工厂就是创建一系列的对象,就像是一个零部件的加工场。比如给车提供零部件可以提供轮胎,底盘,门等。如果为教室提供配件,可以提供,墙、门、窗、黑板,桌椅等。就是对一系列的产品提供风格控制。于其他模式的做对比,其实和创建型模式挺像的,创建这模式提供的是一系列的创建步骤,如果这一系列的创建步骤就是创建这个产品分分别的部件,那么和抽象工厂的价值几乎就相同的了,如果真的是这样,创建者模式的价值也是控制一系列产品的风格。但是通常创建者提供的一系列函数更强调时间上的顺序。也就是说创建在创建产品部件的过程中是有先后顺序的。

需求:坦克大战

创建两种坦克

坦克类型射程速度
b7070米时/70公里
b5050米时/50公里

类图

说明

看到这张类库,可以明显的看到,这里和工厂模式的坦克大战比,是把两个机能,发射和速度当做抽象工厂中的一系列产品。

代码(java实现)

代码(c#实现)

代码(js实现)

代码(c++实现)

#include <iostream>
#include <string>
using namespace std;

class Function{
public:
	string mFunction;
	Function(string str){
		mFunction = str;
	}
	void exe(){
		cout<<mFunction<<"\n";
	}
};

//抽象层
class AbstractShot{
public:
	virtual void fun()=0;
};
class AbstractRun{
public:
	virtual void fun()=0;
};
class AbstractFactory{
public:
	virtual AbstractShot& createShot()=0;
	virtual AbstractRun& createRun()=0;
};
//实施层
class B70Shot: public AbstractShot{
public:
	virtual void fun(){
		Function function("B70Shot:射程70");
		function.exe();
	}
};
class B50Shot: public AbstractShot{
public:
	virtual void fun(){
		Function function("B50Shot:射程50");
		function.exe();	
	}
};
class B70Run: public AbstractRun{
public:
	virtual void fun(){
		Function function("B70Run:速度70");
		function.exe();
	}
};
class B50Run: public AbstractRun{
public:
	virtual void fun(){
		Function function("B50Run:速度50");
		function.exe();	
	}
};


class B70Factory:public AbstractFactory{
public:
	virtual AbstractShot& createShot(){
		return *(new B70Shot());
	}
	virtual AbstractRun& createRun(){
		return *(new B70Run());
	}
};
class B50Factory:public AbstractFactory{
public:
	virtual AbstractShot& createShot(){
		return *(new B50Shot());
	}
	virtual AbstractRun& createRun(){
		return *(new B50Run());
	}
};
// 客户端
class Client{
public:
	static void main(){
		B70Factory b70;
		AbstractFactory& f = b70;
		AbstractShot& s = f.createShot();
		AbstractRun& r = f.createRun();
		s.fun();
		r.fun();
	}
};



//客户端调用
int main()
{
	Function function("抽象工厂模式演示");
	function.exe();
	Client::main();

	//看代码不用考虑以下内容
	int cin_a;
	cin>>cin_a;
	return 0;
}

3.关联链接

4.关联知识

1.

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。它通过定义一个抽象接口来封装对象的创建过程,使得客户端代码与具体实现解耦。

核心思想

  • 产品族:将一组相关的产品(属于同一主题)组合在一起,形成产品族。
  • 抽象工厂:声明创建抽象产品的方法,具体子类实现这些方法以生成具体产品。
  • 客户端依赖抽象:客户端通过抽象接口操作产品,无需关心具体实现。

结构组成

  1. 抽象产品(AbstractProduct)
    定义产品的抽象接口,如 ButtonTextField

  2. 具体产品(ConcreteProduct)
    实现抽象产品的接口,如 WindowsButtonMacButton

  3. 抽象工厂(AbstractFactory)
    声明创建抽象产品的方法,如 createButton()createTextField()

  4. 具体工厂(ConcreteFactory)
    实现抽象工厂的方法,返回具体产品实例,如 WindowsFactoryMacFactory

  5. 客户端(Client)
    通过抽象工厂获取产品实例,仅依赖抽象类型。

适用场景

  • 需要创建多个产品族,且希望系统独立于产品的创建、组合和表示。
  • 系统需要支持多种界面风格(如暗黑主题、明亮主题)。
  • 需要兼容多个数据库(如 MySQL、PostgreSQL)的驱动和连接。
  • 产品族需要一起使用(如 UI 组件的按钮、文本框必须风格统一)。

示例代码(Java)

// 抽象产品:按钮
interface Button {
    void render();
}

// 具体产品:Windows 按钮
class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染 Windows 风格按钮");
    }
}

// 具体产品:Mac 按钮
class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染 Mac 风格按钮");
    }
}

// 抽象产品:文本框
interface TextField {
    void render();
}

// 具体产品:Windows 文本框
class WindowsTextField implements TextField {
    @Override
    public void render() {
        System.out.println("渲染 Windows 风格文本框");
    }
}

// 具体产品:Mac 文本框
class MacTextField implements TextField {
    @Override
    public void render() {
        System.out.println("渲染 Mac 风格文本框");
    }
}

// 抽象工厂
interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

// 具体工厂:Windows 工厂
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
}

// 具体工厂:Mac 工厂
class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        return new MacTextField();
    }
}

// 客户端代码
public class Application {
    private Button button;
    private TextField textField;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        textField = factory.createTextField();
    }

    public void render() {
        button.render();
        textField.render();
    }

    public static void main(String[] args) {
        // 使用 Windows 风格
        Application app1 = new Application(new WindowsFactory());
        app1.render();

        // 使用 Mac 风格
        Application app2 = new Application(new MacFactory());
        app2.render();
    }
}

优点

  1. 隔离具体类:客户端无需知道具体产品的类名。
  2. 易于交换产品族:只需更换工厂即可切换整个产品族。
  3. 保证兼容性:同一工厂创建的产品族必然兼容。

缺点

  1. 扩展复杂:新增产品族需修改抽象工厂接口及所有具体工厂。
  2. 产品族限制:难以支持跨产品族的产品组合(如混合使用 Windows 按钮和 Mac 文本框)。

与工厂方法模式的区别

特性抽象工厂工厂方法
创建对象一族相关对象单一对象
工厂角色多个具体工厂一个具体工厂
扩展性新增产品族困难新增产品容易
典型场景换肤、数据库驱动日志记录器、解析器

总结

抽象工厂模式通过封装产品族的创建逻辑,使得系统能够灵活地切换产品族,同时保持客户端代码的简洁和稳定。适用于需要统一管理多产品依赖关系的场景,但需谨慎权衡扩展性需求。

2.与其他模式配合

抽象工厂模式在创建型模式中具有重要地位,其价值体现在对复杂对象创建场景的抽象和封装,尤其适用于需要管理产品族的场景。以下从地位、核心价值及与其他模式的协作价值展开分析:

一、抽象工厂在创建型模式中的地位

  1. 高级抽象层
    抽象工厂是创建型模式中的“战略层”工具,解决产品族(一组相关产品)的创建问题,而非单个对象的创建。相较于工厂方法(战术层,关注单一产品),它提供更宏观的抽象。

  2. 解耦的终极形态
    通过隔离具体产品类,抽象工厂使客户端完全依赖抽象接口,彻底消除对实现细节的耦合,是依赖倒置原则(DIP)的典范实现。

  3. 框架级设计基础
    许多框架(如GUI工具包、ORM框架)通过抽象工厂实现跨平台/数据库的支持,例如Java的javax.xml.parsers.DocumentBuilderFactory

二、抽象工厂的核心价值

  1. 产品族一致性保证
    确保同一工厂创建的产品族在风格、兼容性上一致(如Windows控件族与Mac控件族),避免混搭导致的问题。

  2. 系统扩展性增强
    新增产品族只需扩展工厂接口和实现,无需修改现有客户端代码,符合开闭原则(OCP)。

  3. 替换实现的灵活性
    通过切换工厂即可更换整个产品族(如从MySQL切换到PostgreSQL),提升系统可配置性和可测试性。

三、与其他模式配合的特殊价值

1. 与工厂方法模式协作
  • 场景:当产品族中的某些产品需要独立扩展时。
  • 协作方式
    抽象工厂定义产品族接口,工厂方法实现具体产品的创建。例如:

    // 抽象工厂定义产品族
    interface GUIFactory {
        Button createButton();          // 委托给工厂方法
        TextField createTextField();    // 委托给工厂方法
    }
    
    // 具体工厂使用工厂方法
    class WindowsFactory implements GUIFactory {
        @Override
        public Button createButton() {
            return new WindowsButton(); // 直接实例化或调用工厂方法
        }
        // ...
    }
  • 价值:结合两种模式的优势,既保证产品族一致性,又为单个产品提供扩展点。
2. 与建造者模式协作
  • 场景:产品族中的对象需要复杂构造过程(如分步骤构建)。
  • 协作方式
    抽象工厂创建建造者,建造者负责具体构造逻辑。例如:

    // 抽象工厂创建建造者
    interface CarFactory {
        CarBuilder createSportsCarBuilder();
    }
    
    // 建造者定义复杂构造步骤
    interface CarBuilder {
        void buildEngine();
        void buildBody();
        Car getResult();
    }
  • 价值:将对象创建分为“选择产品族”(工厂)和“构造细节”(建造者),应对复杂对象的分步骤创建。
3. 与原型模式协作
  • 场景:产品族的创建成本较高,需通过克隆优化性能。
  • 协作方式
    抽象工厂返回原型对象的克隆实例。例如:

    // 抽象工厂返回原型
    interface ShapeFactory {
        Shape createCircle(); // 返回原型实例的克隆
    }
    
    // 具体工厂使用原型
    class PrototypeFactory implements ShapeFactory {
        private static final Circle prototype = new Circle();
        @Override
        public Shape createCircle() {
            return prototype.clone();
        }
    }
  • 价值:避免重复创建昂贵对象,提升性能。
4. 与依赖注入(DI)框架协作
  • 场景:在框架中管理对象生命周期和依赖关系。
  • 协作方式
    依赖注入容器充当抽象工厂,根据配置动态提供产品族实例。例如Spring的@Autowired注入不同数据源的ConnectionFactory
  • 价值:实现运行时动态切换产品族,提升系统可配置性和可测试性。

四、总结:特殊价值的核心逻辑

抽象工厂的特殊价值在于其“接口隔离”与“产品族封装”能力,与其他模式配合时:

  1. 分工明确:抽象工厂负责选择产品族,其他模式负责具体对象的创建或构造
  2. 扩展正交:通过组合模式,可以在不破坏现有结构的前提下,独立扩展产品族或单个产品的创建逻辑。
  3. 框架友好:其设计思想直接支撑了现代框架的扩展机制(如插件化架构、多主题支持)。

因此,抽象工厂不仅是创建型模式中的“战略工具”,更是构建灵活、可扩展系统的关键基础设施。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值