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

模式概述

  • 工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,弥补了缺陷。他也被称为虚拟构造器模式或者多态工厂模式
  • 先定义一个抽象工厂类,再定义具体工厂类去实现抽象工厂类的方法,这种抽象化的结果是:可以在不修改具体工厂类的情况下引进新的产品,如果出现新的功能,只需要为这个功能定义一个具体的工厂类。就可以创建出该功能的实例,这种改进方案,就叫做工厂方法模式。
  • 在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生成具体的产品对象,这样做得目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定久经应该实例化哪一个具体产品类。
  • 总结:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化,工厂方法模式让一个类的实例化延迟到其子类。

模式结构

  1. 抽象产品(定义产品的接口,产品对象的公共父类)
  2. 具体产品(实现产品的接口)
  3. 抽象工厂(声明工厂方法,返回一个产品)
  4. 具体工厂(抽象工厂的子类,客户端调用,返回一个具体的实例)

代码实现

需求: 日志记录器可以通过很多途径保存日志,用户可以修改配置文件,灵活的更换日志记录的方式,为了更好的封装记录器的初始化过程,并保证多种记录器切换的灵活性,使用工厂方法模式设计该系统。

  1. 抽象产品接口: Logger
//抽象产品类
public interface Logger {
	public void writeLog();
}
  1. 具体产品实现: DatabaseLogger,FileLogger
import com.daq.factorymethod.Logger;
public class DatabaseLogger implements Logger {
	@Override
	public void writeLog() {
		System.out.println("数据库日志记录");
	}
}
import com.daq.factorymethod.Logger;
public class FileLogger implements Logger {
	@Override
	public void writeLog() {
		System.out.println("文件日志记录");
	}
}
  1. 抽象工厂接口: LoggerFactory
import com.daq.factorymethod.Logger;

//抽象工厂接口
public interface LoggerFactory {
	//抽象工厂方法
	public Logger createLogger();
}
  1. 具体工厂实现: DatabaseLoggerFactoryFileLoggerFactory
import com.daq.factory.LoggerFactory;
import com.daq.factorymethod.Logger;
import com.daq.factorymethod.Impl.DatabaseLogger;

public class DatabaseLoggerFactory implements LoggerFactory {
	@Override
	public Logger createLogger() {
		//连接数据库
		
		//创建数据库日志记录器对象
		Logger logger = new DatabaseLogger();
		
		//初始化数据库日志记录器
		
		return logger;
	}
}
import com.daq.factory.LoggerFactory;
import com.daq.factorymethod.Logger;
import com.daq.factorymethod.Impl.FileLogger;

public class FileLoggerFactory implements LoggerFactory {
	@Override
	public Logger createLogger() {
		//创建文件日志记录对象
		Logger logger = new FileLogger();
		
		//创建文件
		return logger;
	}
}
  1. 客户端测试: Client
import com.daq.factory.LoggerFactory;
import com.daq.factory.Impl.FileLoggerFactory;
import com.daq.factorymethod.Logger;

public class Client {
	public static void main(String[] args) {
		LoggerFactory factory;
		Logger logger;
		//具体工厂的实例
		factory=new FileLoggerFactory();
		logger=factory.createLogger();
		logger.writeLog();
	}
}
  1. 如果要增加新的功能,只需要对应的增加一个新的具体工厂类,然后在客户端代码中修改具体工厂类的类名,原有类库的代码无需修改。
  2. 通过引入配合文件并使用反射机制可以实现在不修改客户端代码的基础上更换具体共产类,系统更符合开闭原则,具备更好的扩展性。

工厂方法的隐藏

  • 通过把业务方法调用移至工厂类中,可以直接使用工厂对象来调用产品对象的业务方法,客户端无需使用工厂方法来创建产品对象。

优缺点

  • 优点:
    ①用户只需关心所需产品对应的工厂,无需关心创建细节。
    ②基于工厂角色和产品角色的多态性设计是工厂方法模式的关键,工厂方法模式之所以被称为多态工厂模式,正是因为所有的具体工厂类都具有同一抽象父类。
    ③新增功能时,无需修改源码,只增添一个具体工厂和具体产品即可。

  • 缺点:
    ①新增了产品类,意味着系统的复杂度要增加。
    ②代码中引入了抽象层,在客户端中也使用了抽象性进行定义,增加了理解难度。

应用场景

  • 客户端不知道它所需要使用的类,因为客户端只需要知道所对应的工厂就行了。
  • 抽象工厂类通过使用他的子类来指定创建哪个对象。在工厂方法模式中对于抽象工厂只需要提供一个创建产品的接口,而由其子类来决定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时子类对象将覆盖父类对象。

猜你喜欢

转载自blog.csdn.net/weixin_44861399/article/details/105815144