JavaScript设计模式-工厂方法模式

工厂方法模式又称为工厂模式,也叫虚拟构造器模式或者多态工厂模式,属于类创建型模式。在工厂方法模式中,工厂父类定义了创建产品对象的公共接口,而具体的工厂子类则负责生成不同的产品对象。这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,由工厂子类决定创建哪种具体的产品对象。

描述

在简单工厂模式中,类的创建依赖于工厂类,这意味着要扩展程序就必须修改工厂类的代码。相比之下,工厂方法模式将创建的具体过程交给专门的工厂子类去完成,即产品的实例化操作在工厂子类中实现,这样不需要修改工厂类本身,只需定义实现工厂接口的子类即可。

模式分析

工厂方法模式进一步抽象了简单工厂模式的概念。通过使用面向对象的多态特性,工厂方法模式保留了简单工厂模式的优点,同时解决了其缺点。工厂方法模式中,核心工厂类不再负责所有产品的创建工作,而是将创建工作交由子类来实现。核心工厂类仅定义创建产品的方法接口,而不关心具体哪个产品类被实例化,这使得可以在不修改工厂角色的情况下引入新产品。

模式结构

  • Product:抽象产品
  • ConcreteProduct:具体产品
  • Factory:抽象工厂
  • ConcreteFactory:具体工厂

实现

工厂方法模式的核心思想是将对象的创建延迟到子类中。在 JavaScript 中没有传统的抽象类机制,但我们可以通过定义接口的方式来实现工厂方法模式的思想。

示例:日志记录器
// 抽象产品类
class Logger {
    log(message) {
        throw new Error("This method should be implemented by subclasses");
    }
}

// 具体产品类:文件记录器
class FileLogger extends Logger {
    log(message) {
        console.log(`Writing "${message}" to a file.`);
    }
}

// 具体产品类:控制台记录器
class ConsoleLogger extends Logger {
    log(message) {
        console.log(`Logging to console: ${message}`);
    }
}

// 具体产品类:网络记录器
class NetworkLogger extends Logger {
    log(message) {
        console.log(`Sending "${message}" to a remote server.`);
    }
}

// 抽象工厂类
class LoggerFactory {
    createLogger() {
        throw new Error("This method should be implemented by subclasses");
    }
}

// 具体工厂类:文件记录器工厂
class FileLoggerFactory extends LoggerFactory {
    createLogger() {
        return new FileLogger();
    }
}

// 具体工厂类:控制台记录器工厂
class ConsoleLoggerFactory extends LoggerFactory {
    createLogger() {
        return new ConsoleLogger();
    }
}

// 具体工厂类:网络记录器工厂
class NetworkLoggerFactory extends LoggerFactory {
    createLogger() {
        return new NetworkLogger();
    }
}

// 使用工厂方法创建不同的日志记录器
const fileLogger = new FileLoggerFactory().createLogger();
fileLogger.log("This is a file log entry."); // Writing "This is a file log entry." to a file.

const consoleLogger = new ConsoleLoggerFactory().createLogger();
consoleLogger.log("This is a console log entry."); // Logging to console: This is a console log entry.

const networkLogger = new NetworkLoggerFactory().createLogger();
networkLogger.log("This is a network log entry."); // Sending "This is a network log entry." to a remote server.
优化工厂方法的使用

在实际开发中,我们可以将日志工厂进一步简化成一个工厂管理器,由它负责返回不同的日志工厂实例,从而简化调用者的使用。

class LoggerFactoryManager {
    static getFactory(type) {
        switch (type) {
            case "file":
                return new FileLoggerFactory();
            case "console":
                return new ConsoleLoggerFactory();
            case "network":
                return new NetworkLoggerFactory();
            default:
                throw new Error("Unknown Logger Type");
        }
    }
}

const logger = LoggerFactoryManager.getFactory("network").createLogger();
logger.log("This is a dynamic network log entry.");

优点

  • 隐藏创建细节:工厂方法模式隐藏了具体产品的创建过程,客户端只需关心对应工厂,而不必了解具体的产品创建细节。
  • 多态性:工厂方法模式利用多态设计,工厂可以自主决定创建哪个产品对象,创建细节完全封装在具体工厂中。
  • 开放封闭原则:增加新产品时,只需添加新的工厂和产品类,不必修改已有工厂和产品类,从而增强了系统的扩展性。

缺点

  • 类增加:每增加一种新产品,必须新增一个具体产品类和一个对应的具体工厂类,系统中类的数量成对增加,增大了系统的复杂度。
  • 抽象性:由于引入了抽象层,客户端代码中需要使用抽象层定义产品,增加了系统的理解难度。

工厂方法模式适合于产品种类较多且经常变动的系统,通过子类来动态扩展和创建具体产品,避免了对已有代码的直接修改,有利于扩展和维护。

原文链接:

https://anyaowl.cn/blog/detail/12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值