设计模式-创建型模式:抽象工厂

抽象工厂模式是一种创建相关或依赖对象家族的模式,常用于多个产品族的创建。它提供了创建相关产品的方法,允许客户端通过抽象接口创建而不关注具体类。此模式在系统需要灵活更换产品族,如数据库访问对象创建时非常有用,但会增加系统的复杂度。

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

1、简介

抽象工厂(Abstract Factory)模式是一种创建型设计模式,它提供了一种方法创建相关或依赖对象的家族,而不需要明确指定它们的具体类。

在抽象工厂模式中,有一个抽象工厂类,它负责创建一组相关或依赖的对象。它包含多个用于创建不同对象的方法,每个方法都返回一个抽象产品类型的对象。

具体工厂类是抽象工厂的子类,它实现了在抽象工厂中声明的方法。每个具体工厂类可以创建多个具体产品类的实例。

抽象产品是一个接口或抽象类,它声明了由具体产品实现的方法。

具体产品是实现了抽象产品接口的具体类,每个具体产品类都定义了一组具体的方法。

2、适用情况

抽象工厂模式适用的情况包括:

①当系统中有多个产品族,每个产品族中又包含多个产品时。

例如,在一个汽车生产系统中,可能有多种品牌的汽车,每种品牌又有多种车型。在这种情况下,可以使用抽象工厂模式来创建不同品牌的汽车。

②当系统需要提供一组产品,而这些产品是相关的,或者属于同一类别时。

例如,在一个家庭生活系统中,可能需要提供一组家电产品,如冰箱、洗衣机、空调等。在这种情况下,可以使用抽象工厂模式来创建这些家电产品。

3、优缺点

优点:

抽象工厂模式提供了一种方法创建相关或依赖对象的家族。

它允许客户端使用抽象接口来创建产品,而不需要知道实际产品的类名。

抽象工厂模式可以使系统具有更好的灵活性,因为可以轻松地替换具体工厂。

缺点:

抽象工厂模式增加了系统的复杂度

因为客户端需要知道所有的具体工厂类才能使用它们。

如果系统中涉及的产品族较多,或者每个产品族中的产品较多,那么就需要定义很多的具体工厂类,这会增加系统的复杂度。

4、代码实现

interface AbstractFactory {
    //抽象工厂
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

class ConcreteFactory1 implements AbstractFactory {
    //具体工厂
    @Override
    public AbstractProductA createProductA() {
        //具体产品
        return new ConcreteProductA1();
    }
    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

class ConcreteFactory2 implements AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }
    @Override
    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

interface AbstractProductA {
    void methodA();
}

class ConcreteProductA1 implements AbstractProductA {
    @Override
    public void methodA() {
        // 实现方法A
        System.out.println("A1");

    }
}

class ConcreteProductA2 implements AbstractProductA {
    @Override
    public void methodA() {
        // 实现方法A
        System.out.println("A2");

    }
}

interface AbstractProductB {
    void methodB();
}

class ConcreteProductB1 implements AbstractProductB {
    @Override
    public void methodB() {
        // 实现方法B
        System.out.println("B1");

    }
}

class ConcreteProductB2 implements AbstractProductB {
    @Override
    public void methodB() {
        // 实现方法B
        System.out.println("B2");

    }
}

public class test {
    public static void main(String[] args) {
        AbstractFactory factory = new ConcreteFactory1();
        AbstractProductA productA = factory.createProductA();
        AbstractProductB productB = factory.createProductB();
        productA.methodA();

    }
}

定义了抽象工厂和抽象产品两个接口,然后使用具体工厂实现具体产品,如图所示,在客户端代码中,通过抽象工厂得到具体工厂、具体工厂创造具体产品的方式来创建产品

总的来说,抽象工厂模式是一种有用的设计模式,它可以解决多个产品族的创建问题,但是在使用时应该根据系统的具体情况进行选择。

5、应用场景

常见的抽象工厂模式的应用场景是创建数据库访问对象

例如,我们有一个系统需要连接到不同的数据库(Oracle, MySQL, SQL Server等),并执行不同的SQL语句。我们可以使用抽象工厂模式来实现这个功能。

首先定义抽象工厂接口DBConnectionFactory,其中定义了创建数据库连接和命令的抽象方法:

interface DBConnectionFactory {
    DBConnection createDBConnection();
    DBCommand createDBCommand();
}

然后为不同数据库创建具体的工厂类,例如 OracleDBConnectionFactory, MySqlDBConnectionFactory, SqlServerDBConnectionFactory,实现对应数据库连接和命令

class OracleDBConnectionFactory implements DBConnectionFactory {
    public DBConnection createDBConnection() {
        return new OracleDBConnection();
    }
    public DBCommand createDBCommand() {
        return new OracleDBCommand();
    }
}
class MySqlDBConnectionFactory implements DBConnectionFactory {
    public DBConnection createDBConnection() {
        return new MySqlDBConnection();
    }
    public DBCommand createDBCommand() {
        return new MySqlDBCommand();
    }
}

最后,在系统中只需要在运行时指定使用哪个工厂来创建数据库访问对象即可

DBConnectionFactory factory = getDBConnectionFactory();
DBConnection conn = factory.createDBConnection();
DBCommand cmd = factory.createDBCommand();

这样,当需要在不同数据库上运行系统时,只需要在 getDBConnectionFactory() 中返回不同的工厂实例即可创建不同数据库的访问对象。 这样就不需要在系统中做大量的if else判断,可以在类层次中使用继承来实现可拓展性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逐梦苍穹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值