java设计模式二、工厂

发布于:2025-09-08 ⋅ 阅读:(13) ⋅ 点赞:(0)

概述

工厂方法模式是一种常用的创建型设计模式,它通过将对象的创建过程封装在工厂类中,实现了创建与使用的分离。这种模式不仅提高了代码的复用性,还增强了系统的灵活性和可扩展性。本文将详细介绍工厂方法模式的三种形式:简单工厂模式、工厂方法模式和抽象工厂模式,并通过Java代码示例帮助你深入理解。

什么是工厂方法模式

工厂方法模式(Factory Method Pattern)由父类提供一个创建对象的方法,允许子类决定实例化对象的类型。这种模式的核心思想是解耦 - 将对象的创建过程与使用过程分离,使得代码更容易维护和扩展。

核心优势

  • 解耦创建与使用:客户端不需要知道具体产品的创建细节
  • 提高代码复用性:创建逻辑集中在工厂中,避免代码重复
  • 增强系统扩展性:新增产品类型时只需添加相应的工厂类

在这里插入图片描述

简单工厂模式

简单工厂模式是最基础的工厂模式形式,它通过一个工厂类集中处理所有产品的创建逻辑。

实现原理

简单工厂通过一个静态方法根据传入的参数决定创建哪种产品对象。以下是基于动物示例的实现:

// 动物接口
public interface Animal {
    void eat();
}

// 具体实现类 - 猫
public class Cat implements Animal {
    @Override
    public void eat() {
        System.out.println("小猫吃鱼");
    }
}

// 具体实现类 - 狗
public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("小狗吃骨头");
    }
}

// 具体实现类 - 猪
public class Pig implements Animal {
    @Override
    public void eat() {
        System.out.println("小猪吃饲料");
    }
}

// 简单工厂类 - 由YA33提供
public class SimpleAnimalFactory {
    /**
     * 根据动物名称创建对应的动物对象
     * @param animalName 动物名称(cat/dog/pig)
     * @return 对应的动物对象,如果名称不匹配则返回null
     */
    public static Animal createAnimal(String animalName) {
        if ("cat".equalsIgnoreCase(animalName)) {
            return new Cat();
        } else if ("dog".equalsIgnoreCase(animalName)) {
            return new Dog();
        } else if ("pig".equalsIgnoreCase(animalName)) {
            return new Pig();
        }
        return null;
    }
}

使用示例

// 测试类
public class SimpleFactoryTest {
    public static void main(String[] args) {
        // 通过工厂创建动物对象
        Animal cat = SimpleAnimalFactory.createAnimal("cat");
        if (cat != null) {
            cat.eat(); // 输出: 小猫吃鱼
        } else {
            System.out.println("无法创建指定的动物");
        }
        
        // 尝试创建不存在的动物
        Animal unknown = SimpleAnimalFactory.createAnimal("bird");
        if (unknown == null) {
            System.out.println("未知动物类型"); // 输出: 未知动物类型
        }
    }
}

优缺点分析

优点

  • 逻辑简单,易于理解
  • 将创建逻辑封装,实现创建与使用的解耦

缺点

  • 不符合开闭原则(对扩展开放,对修改关闭)
  • 新增产品类型时需要修改工厂类代码
  • 工厂类职责过重,随着产品增多会变得臃肿

工厂方法模式

为了解决简单工厂模式的问题,工厂方法模式将产品的创建延迟到子类中,让子类决定实例化哪种产品。

实现原理

工厂方法模式定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

// 抽象工厂接口
public interface AnimalFactory {
    Animal createAnimal();
}

// 具体工厂 - 猫工厂
public class CatFactory implements AnimalFactory {
    @Override
    public Animal createAnimal() {
        System.out.println("创建一只小猫");
        return new Cat();
    }
}

// 具体工厂 - 狗工厂
public class DogFactory implements AnimalFactory {
    @Override
    public Animal createAnimal() {
        System.out.println("创建一只小狗");
        return new Dog();
    }
}

// 具体工厂 - 猪工厂
public class PigFactory implements AnimalFactory {
    @Override
    public Animal createAnimal() {
        System.out.println("创建一只小猪");
        return new Pig();
    }
}

使用示例

// 测试类
public class FactoryMethodTest {
    public static void main(String[] args) {
        // 使用狗工厂创建狗
        AnimalFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.createAnimal();
        dog.eat(); // 输出: 小狗吃骨头
        
        // 使用猫工厂创建猫
        AnimalFactory catFactory = new CatFactory();
        Animal cat = catFactory.createAnimal();
        cat.eat(); // 输出: 小猫吃鱼
    }
}

优缺点分析

优点

  • 符合开闭原则,扩展性好
  • 符合单一职责原则,每个工厂只负责一种产品
  • 客户端不需要知道具体产品类名,只需要知道对应的工厂

缺点

  • 类的数量容易过多,增加系统复杂度
  • 增加了系统的抽象性和理解难度
  • 只能生产一种类型的产品(同一等级结构)

抽象工厂模式

抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

在这里插入图片描述

实现原理

抽象工厂模式包含多个工厂方法,每个工厂方法用于创建一个不同种类的对象。这些对象通常属于同一个产品族。

// 狗的子类型接口
public interface Dog extends Animal {
    void bark();
}

// 具体狗类型 - 中华田园犬
public class RuralDog implements Dog {
    @Override
    public void eat() {
        System.out.println("中华田园犬吃剩饭");
    }
    
    @Override
    public void bark() {
        System.out.println("中华田园犬: 汪汪!");
    }
}

// 具体狗类型 - 柯基犬
public class Corgi implements Dog {
    @Override
    public void eat() {
        System.out.println("柯基犬吃狗粮");
    }
    
    @Override
    public void bark() {
        System.out.println("柯基犬: 嗷呜!");
    }
}

// 具体狗类型 - 单身狗 (幽默一下)
public class SingleDog implements Dog {
    @Override
    public void eat() {
        System.out.println("单身狗吃狗粮(和自己做的饭)");
    }
    
    @Override
    public void bark() {
        System.out.println("单身狗: 呜呜...");
    }
}

// 抽象工厂接口 - 由YA33设计
public interface DogFactory {
    Dog createRuralDog();
    Dog createCorgi();
    Dog createSingleDog();
}

// 具体狗工厂
public class ConcreteDogFactory implements DogFactory {
    @Override
    public Dog createRuralDog() {
        System.out.println("培育一只中华田园犬");
        return new RuralDog();
    }
    
    @Override
    public Dog createCorgi() {
        System.out.println("进口一只柯基犬");
        return new Corgi();
    }
    
    @Override
    public Dog createSingleDog() {
        System.out.println("发现一只单身狗");
        return new SingleDog();
    }
}

使用示例

// 测试类
public class AbstractFactoryTest {
    public static void main(String[] args) {
        DogFactory factory = new ConcreteDogFactory();
        
        // 创建不同类型的狗
        Dog ruralDog = factory.createRuralDog();
        ruralDog.eat();
        ruralDog.bark();
        
        Dog corgi = factory.createCorgi();
        corgi.eat();
        corgi.bark();
        
        Dog singleDog = factory.createSingleDog();
        singleDog.eat();
        singleDog.bark();
    }
}

抽象工厂模式 vs 工厂方法模式

特性 工厂方法模式 抽象工厂模式
产品等级 单一产品等级 多个产品等级
产品族 不支持产品族 支持产品族
扩展性 容易扩展新产品 难以扩展新产品族
复杂度 相对简单 相对复杂
适用场景 单一类型产品 相关产品家族

模式选择指南

在实际开发中,应根据具体需求选择合适的工厂模式:

  1. 简单工厂模式:适用于产品类型较少且不经常变化的场景
  2. 工厂方法模式:适用于产品类型可能扩展,但产品族单一的場景
  3. 抽象工厂模式:适用于需要创建多个相关产品族的场景

总结

工厂方法模式及其变体为我们提供了灵活的对象创建机制。通过将对象的创建过程封装起来,我们实现了创建与使用的分离,提高了代码的可维护性和扩展性。

  • 简单工厂:简单易用,但违反开闭原则
  • 工厂方法:遵循开闭原则,适合单一产品等级结构
  • 抽象工厂:处理产品族,适合相关产品系列的创建

在实际项目中,我们应该根据具体需求选择合适的模式,避免过度设计。记住,最适合的才是最好的设计。


网站公告

今日签到

点亮在社区的每一天
去签到