Java 设计模式 — 抽象工厂模式

一、抽象工厂模式概述

1. 定义

抽象工厂模式(Abstract Factory Pattern)属于创建型设计模式。它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。该模式将对象的创建与使用分离,使得系统在创建对象时具有更高的灵活性和可维护性。

2. 适用场景

  1. 创建系列相关对象:当系统需要创建一系列相关或相互依赖的对象时。例如在游戏开发场景中,需要创建角色、武器、道具等一系列关联对象,且创建过程复杂,抽象工厂模式能很好地组织和管理这些对象的创建。
  2. 解耦具体实现:当系统希望与具体的产品实现解耦,即代码不依赖于产品的具体类,而是依赖于抽象产品接口时。抽象工厂模式通过抽象工厂和抽象产品接口实现解耦,便于系统的扩展和维护。

3. 角色构成

  1. 抽象工厂角色(AbstractFactory)

    • 核心角色,声明了一系列创建产品对象的抽象方法,通常返回抽象产品类型。
    • 例如在图形绘制系统中,抽象工厂可能定义创建抽象图形(如圆形、矩形)的方法。
    • 它不负责创建具体对象,而是将任务交给具体工厂子类,为系统提供统一的对象获取接口。
  2. 具体工厂角色(ConcreteFactory)

    • 实现抽象工厂声明的抽象方法,负责创建具体的产品对象。
    • 例如游戏开发中的“中世纪风格工厂”(MedievalFactory)和“科幻风格工厂”(SciFiFactory)。
    • 每个具体工厂对应一个特定的产品族,所创建的产品对象之间具有关联性和一致性(如中世纪工厂创建骑士、长剑、魔法药水)。
  3. 抽象产品角色(AbstractProduct)

    • 定义产品对象的公共接口,声明基本操作和属性。
    • 例如抽象图形类可能定义 draw()getArea() 等方法。
    • 使得系统可以统一处理不同类型的产品对象,提高灵活性。
  4. 具体产品角色(ConcreteProduct)

    • 抽象产品的具体实现类,提供具体的产品功能。
    • 例如 Knight 类实现 AbstractCharacter 接口,提供生命值、攻击力等属性及攻击、防御等行为。

二、抽象工厂模式示例代码

1. 抽象工厂类

定义创建一系列产品的抽象接口。

// 抽象工厂类
public abstract class AbstractFactory {
    // 创建角色的抽象方法
    public abstract Character createCharacter();
    // 创建武器的抽象方法
    public abstract Weapon createWeapon();
    // 创建道具的抽象方法
    public abstract Item createItem();
}

2. 具体工厂类

具体工厂实现抽象工厂接口,负责生产特定产品族的对象。

中世纪风格工厂类

// 中世纪风格工厂类
public class MedievalFactory extends AbstractFactory {
    @Override
    public Character createCharacter() {
        return new Knight();
    }

    @Override
    public Weapon createWeapon() {
        return new LongSword();
    }

    @Override
    public Item createItem() {
        return new MagicPotion();
    }
}

科幻风格工厂类

// 科幻风格工厂类
public class SciFiFactory extends AbstractFactory {
    @Override
    public Character createCharacter() {
        return new Robot();
    }

    @Override
    public Weapon createWeapon() {
        return new LaserGun();
    }

    @Override
    public Item createItem() {
        return new EnergyShield();
    }
}

3. 抽象产品类

定义各类产品的公共接口。

抽象角色类

// 抽象角色类
public abstract class Character {
    public abstract void attack();
    public abstract void defend();
}

抽象武器类

// 抽象武器类
public abstract class Weapon {
    public abstract void use();
}

抽象道具类

// 抽象道具类
public abstract class Item {
    public abstract void use();
}

4. 具体产品类

实现抽象产品接口,提供具体功能。

骑士角色类

// 骑士角色类
public class Knight extends Character {
    @Override
    public void attack() {
        System.out.println("骑士挥舞长剑攻击!");
    }

    @Override
    public void defend() {
        System.out.println("骑士举起盾牌防御!");
    }
}

长剑武器类

// 长剑武器类
public class LongSword extends Weapon {
    @Override
    public void use() {
        System.out.println("使用长剑进行攻击,造成高额伤害!");
    }
}

魔法药水道具类

// 魔法药水道具类
public class MagicPotion extends Item {
    @Override
    public void use() {
        System.out.println("使用魔法药水,恢复生命值!");
    }
}

机器人角色类

// 机器人角色类
public class Robot extends Character {
    @Override
    public void attack() {
        System.out.println("机器人发射激光攻击!");
    }

    @Override
    public void defend() {
        System.out.println("机器人启动能量护盾防御!");
    }
}

激光枪武器类

// 激光枪武器类
public class LaserGun extends Weapon {
    @Override
    public void use() {
        System.out.println("使用激光枪射击,具有强大的攻击力!");
    }
}

能量护盾道具类

// 能量护盾道具类
public class EnergyShield extends Item {
    @Override
    public void use() {
        System.out.println("启动能量护盾,抵挡攻击!");
    }
}

5. 测试类

客户端通过抽象工厂接口创建对象,无需关心具体实现。

// 测试类
public class Test {
    public static void main(String[] args) {
        // 创建中世纪风格工厂
        AbstractFactory medievalFactory = new MedievalFactory();
        // 创建中世纪风格对象族
        Character knight = medievalFactory.createCharacter();
        Weapon longSword = medievalFactory.createWeapon();
        Item magicPotion = medievalFactory.createItem();

        knight.attack();
        longSword.use();
        magicPotion.use();

        // 创建科幻风格工厂
        AbstractFactory sciFiFactory = new SciFiFactory();
        // 创建科幻风格对象族
        Character robot = sciFiFactory.createCharacter();
        Weapon laserGun = sciFiFactory.createWeapon();
        Item energyShield = sciFiFactory.createItem();

        robot.attack();
        laserGun.use();
        energyShield.use();
    }
}

三、总结

抽象工厂模式通过抽象工厂、具体工厂、抽象产品和具体产品等角色的协作,实现了创建一系列相关或相互依赖对象的功能。其核心优势在于:

  • 灵活性:系统在创建对象时更加灵活,易于维护。
  • 解耦:有效解耦了对象的创建和使用过程。
  • 扩展性:便于根据需求变化快速添加新的产品族(如新增“魔法风格工厂”),而无需修改现有代码。

在实际应用中,当面临需要创建多个相关对象且希望保持系统的扩展性和灵活性时,抽象工厂模式是一个非常有效的解决方案。它有助于开发人员更好地组织代码结构,提高软件系统的质量。