设计模式-工厂模式实现

一、简单工厂

定义

简单工厂模式是一种类的行为型模式,它通过专门的工厂类来创建对象,客户端不直接创建对象,而是通过工厂类来创建

实现示例

饮料产品

// Step 1: 定义抽象产品
interface Drink {
    void prepare();
}

// Step 2: 定义具体产品
class Coffee implements Drink {
    @Override
    public void prepare() {
        System.out.println("Preparing Coffee.");
    }
}

class Tea implements Drink {
    @Override
    public void prepare() {
        System.out.println("Preparing Tea.");
    }
}

class Juice implements Drink {
    @Override
    public void prepare() {
        System.out.println("Preparing Juice.");
    }
}

// Step 3: 创建工厂类
class DrinkFactory {
    public static Drink createDrink(String drinkType) {
        if (drinkType == null || drinkType.isEmpty()) {
            throw new IllegalArgumentException("Drink type must not be null or empty.");
        }
        switch (drinkType.toLowerCase()) {
            case "coffee":
                return new Coffee();
            case "tea":
                return new Tea();
            case "juice":
                return new Juice();
            default:
                throw new IllegalArgumentException("Unknown drink type: " + drinkType);
        }
    }
}

// Step 4: 测试客户端代码
public class SimpleFactoryExample {
    public static void main(String[] args) {
        // 使用工厂创建不同的饮料对象
        Drink coffee = DrinkFactory.createDrink("coffee");
        Drink tea = DrinkFactory.createDrink("tea");
        Drink juice = DrinkFactory.createDrink("juice");

        // 调用它们的 prepare 方法
        coffee.prepare();
        tea.prepare();
        juice.prepare();
    }
}

简单工厂模式的特点

  • 优点
    • 将对象的创建逻辑封装到工厂中,减少客户端对具体实现类的依赖。
    • 更易于管理和扩展,添加新产品时只需修改工厂类。
  • 缺点
    • 工厂类的职责可能会变得很重,违背单一职责原则。
    • 不够灵活,修改工厂逻辑时需要重新编译。

适用场景

简单工厂模式适用于产品数量较少且不会频繁变动,创建逻辑不复杂的场景,比如:

  • 创建特定种类的饮料、文档处理器、或者日志记录器。

二、工厂方法模式

定义

工厂方法模式是一种类的行为型模式,它定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法模式让类的实例化推迟到子类。

实现示例

日志记录系统

在不同环境下需要记录日志,比如控制台日志、文件日志等。使用工厂方法模式可以动态选择日志记录器

// Step 1: 定义抽象产品
interface Logger {
    void log(String message);
}

// Step 2: 创建控制台日志
class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("Console Logger: " + message);
    }
}

// Step 2: 创建文件日志
class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("File Logger: " + message + " (logged to a file)");
    }
}

// Step 3: 定义抽象工厂
abstract class LoggerFactory {
    // 工厂方法,返回具体产品
    public abstract Logger createLogger();

    // 工厂方法模式中的模板方法
    public void logMessage(String message) {
        Logger logger = createLogger();
        logger.log(message);
    }
}

// Step 4: 创建具体工厂
class ConsoleLoggerFactory extends LoggerFactory {
    @Override
    public Logger createLogger() {
        return new ConsoleLogger();
    }
}

class FileLoggerFactory extends LoggerFactory {
    @Override
    public Logger createLogger() {
        return new FileLogger();
    }
}

// Step 5: 测试客户端代码
public class FactoryMethodExample {
    public static void main(String[] args) {
        // 使用控制台日志记录器工厂
        LoggerFactory consoleLoggerFactory = new ConsoleLoggerFactory();
        consoleLoggerFactory.logMessage("This is a console log message.");

        // 使用文件日志记录器工厂
        LoggerFactory fileLoggerFactory = new FileLoggerFactory();
        fileLoggerFactory.logMessage("This is a file log message.");
    }
}

工厂方法模式的特点

优点

  1. 开放/封闭原则
    • 新增具体产品时,只需添加新的具体工厂类,无需修改现有代码
  2. 单一职责
    • 工厂类负责产品的创建逻辑,产品类只关注自己的功能
  3. 可扩展性强
    • 当需要新增日志类型(如数据库日志)时,只需添加新的日志类和工厂类即可

缺点

  • 每增加一个产品就需要增加一个对应的工厂类,类的数量会增多

使用场景

当系统中有多个产品家族,每个家族中的产品需要有不同的实现时,可以使用工厂方法模式

  • 日志框架: 根据环境动态创建控制台、文件、数据库日志记录器
  • 数据库连接: 根据不同的数据库类型(MySQL、Oracle)动态创建连接对象
  • UI 工具库: 在不同平台(Windows、macOS)生成对应的按钮或窗口

三、抽象工厂模式

定义

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

实现示例

创建不同族的形状和颜色对象

// Step 1: 定义抽象产品接口
interface Shape {
    void draw();
}

interface Color {
    void fill();
}

// Step 2: 创建具体产品类
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Circle.");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Rectangle.");
    }
}

class Red implements Color {
    @Override
    public void fill() {
        System.out.println("Filling with Red color.");
    }
}

class Blue implements Color {
    @Override
    public void fill() {
        System.out.println("Filling with Blue color.");
    }
}

// Step 3: 定义抽象工厂
interface AbstractFactory {
    Shape createShape(String shapeType);
    Color createColor(String colorType);
}

// Step 4: 创建具体工厂类
class ShapeFactory implements AbstractFactory {
    @Override
    public Shape createShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        switch (shapeType.toLowerCase()) {
            case "circle":
                return new Circle();
            case "rectangle":
                return new Rectangle();
            default:
                throw new IllegalArgumentException("Unknown shape type: " + shapeType);
        }
    }

    @Override
    public Color createColor(String colorType) {
        // ShapeFactory 不负责创建颜色
        return null;
    }
}

class ColorFactory implements AbstractFactory {
    @Override
    public Color createColor(String colorType) {
        if (colorType == null) {
            return null;
        }
        switch (colorType.toLowerCase()) {
            case "red":
                return new Red();
            case "blue":
                return new Blue();
            default:
                throw new IllegalArgumentException("Unknown color type: " + colorType);
        }
    }

    @Override
    public Shape createShape(String shapeType) {
        // ColorFactory 不负责创建形状
        return null;
    }
}

// Step 5: 创建工厂生成器
class FactoryProducer {
    public static AbstractFactory getFactory(String factoryType) {
        if (factoryType == null) {
            return null;
        }
        switch (factoryType.toLowerCase()) {
            case "shape":
                return new ShapeFactory();
            case "color":
                return new ColorFactory();
            default:
                throw new IllegalArgumentException("Unknown factory type: " + factoryType);
        }
    }
}

// Step 6: 测试客户端代码
public class AbstractFactoryPatternExample {
    public static void main(String[] args) {
        // 获取形状工厂
        AbstractFactory shapeFactory = FactoryProducer.getFactory("shape");
        Shape circle = shapeFactory.createShape("circle");
        Shape rectangle = shapeFactory.createShape("rectangle");

        // 调用形状方法
        circle.draw();
        rectangle.draw();

        // 获取颜色工厂
        AbstractFactory colorFactory = FactoryProducer.getFactory("color");
        Color red = colorFactory.createColor("red");
        Color blue = colorFactory.createColor("blue");

        // 调用颜色方法
        red.fill();
        blue.fill();
    }
}

优点

  • 支持创建多个产品族(如 ShapeColor
  • 工厂类与客户端代码解耦,增加新产品族时无需修改现有代码

使用场景

  • 抽象工厂模式适用于系统需要创建多个相互关联的产品族时,例如主题管理(按钮、窗口、文本框等组件)或游戏开发中的不同种族的单位(如精灵族、兽族)

四、三种模式对比

相同点

  • 都属于工厂模式,用于创建对象
  • 都将对象的创建和使用分离,提高代码的可维护性和扩展性
不同点
简单工厂模式最简单,只有一个工厂类
扩展性差,增加新产品需要修改工厂类
适用于产品种类较少且不会频繁变动的场景
工厂方法模式相对复杂,有抽象工厂和具体工厂
扩展性较好,增加新产品只需要添加新的具体工厂类
适用于产品种类较多且可能频繁变动的场景
抽象工厂模式最复杂,有抽象工厂、具体工厂、抽象产品和具体产品
扩展性最好,增加新的产品族只需要添加新的具体工厂类,但增加新的产品等级结构较困难
适用于多个产品家族且产品之间有依赖关系的场景
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿绵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值