设计模式-创建型-工厂方法

介绍

工厂方法是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。

场景

假如我们开发项目中的日志模块,业务初期只有控制台日志,大部分代码都在控制台日志类。随着业务发展,希望可以增加文件日志功能。

如果代码之间已经存在耦合关系,此时向程序添加新类并不是一件简单的事情。目前大部分代码都与控制台日志类有关。添加文件日志类需要修改全部代码,更可怕的是以后万一要拓展其他日志类,很可能需要再次大幅修改代码。

如此反复反复,恭喜成功诞生一份不可维护的祖传代码。 😂

解决方案

工厂方法模式建议使用特殊的工厂方法代替直接调用 new 关键字创建对象。工厂方法返回的对象通常被称作“产品”。

public abstract class Logger {
    public abstract void log();
}
public class ConsoleLogger extends Logger {
    @Override
    public void log() {
        System.out.println("我是控制台日志器!");
    }
}
public class FileLogger extends Logger {
    @Override
    public void log() {
        System.out.println("我是文件日志器!");
    }
}

紧接着我们再创建一个工厂类,这里声明为抽象类,并且设置一个抽象方法,强制子类实现抽象方法。你也可以设置不设置成抽象类,在基础工厂方法中返回默认类型。

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

乍看之下,工厂方法模式看起来毫无意义,只是改变了程序中调用构造函数的位置而已。但是我们可以在子类里重写工厂方法,从而改变其创建产品的类型。

但有一点需要注意,仅当这些产品具有共同的父类或者接口时,工厂子类才能返回不同类型的产品。同时工厂基类的工厂方法还应将其返回类型声明为共有接口。

只要产品类实现一个共同的接口,就可以将它传递给客户代码,而无需提供任何额外的数据。

public class Application {

    private final LoggerFactory loggerFactory;

    public Application(LoggerFactory loggerFactory) {
        this.loggerFactory = loggerFactory;
    }

    public void run() {
        Logger logger = loggerFactory.createLogger();
        logger.log();
    }
}

客户端代码仅通过抽象类型使用工厂和产品,如需要添加新的产品,仅需实现工厂抽象类和产品抽象类即可。无需修改原有的工厂或者产品类。

总结

这是重新学习单例模式的笔记,其中可能有很多地方写的不对,写得不好,欢迎大家指正 👏。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Hello。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!