工厂方法模式 - 抽象工厂与抽象产品的结合

工厂方法模式是在简单工厂模式上再加了一层,添加了一个抽象工厂和具体工厂。即不再使用一个工厂类来统一负责所有产品的创建,而是把创建具体产品的任务交给了专门的工厂子类去完成。比如说,我要生产矩形、圆形、菱形这三种形状,就不再使用一个工厂了,而是让矩形工厂、圆形工厂、菱形工厂去完成,而这三个工厂又是形状工厂(抽象工厂)的子工厂。如果我们想要新生产一个椭圆形,只需要新增一个椭圆形工厂就行,让椭圆形工厂去完成生产。这更符合开闭原则。

定义

定义一个用于创建对象的接口,但是让子类决定哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

 

结构

Product(抽象产品)

定义产品的接口,所有具体产品的公共父类。

ConcreteProduct(具体产品)

实现了抽象产品接口,由专门的具体工厂创建,具体工厂与具体产品之间一一对应。

Factory(抽象工厂)

声明了工厂方法,用于返回同一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。

ConcreteFactory(具体工厂)

抽象工厂的子类,实现了抽象工厂中声明的工厂方法,可以由客户端调用,返回一个具体产品的实例。

 

Spring中也用到了工厂方法模式,一般情况下,应用程序有自己的工厂对象来创建bean。如果将应用程序自己的工厂对象交给Spring管理,那么Spring管理的就不是普通的bean,而是工厂Bean。

 

应用实例 - 日志记录器

/**
 * 
 * @ClassName Log
 * @Description 日志记录器接口 - 抽象产品
 * @Author 柳成荫
 * @Date 2019年9月21日
 * @Version V1.0.0
 */
public interface Log {
	void writeLog();
}
/**
 * 
 * @ClassName FileLog
 * @Description 文件记录器 - 具体产品
 * @Author 柳成荫
 * @Date 2019年9月21日
 * @Version V1.0.0
 */
public class FileLog implements Log {

	@Override
	public void writeLog() {
		System.out.println("文件日志记录");
	}

}
/**
 * 
 * @ClassName DatabaseLog
 * @Description 数据库日志记录 - 具体产品
 * @Author 柳成荫
 * @Date 2019年9月21日
 * @Version V1.0.0
 */
public class DatabaseLog implements Log {

	@Override
	public void writeLog() {
		System.out.println("数据库日志记录");
	}

}
/**
 * 
 * @ClassName LogFactory
 * @Description 日志记录工厂接口 - 抽象工厂
 * @Author 柳成荫
 * @Date 2019年9月21日
 * @Version V1.0.0
 */
public interface LogFactory {
	Log createLog();
}
/**
 * 
 * @ClassName FileLogFactory
 * @Description 文件日志记录器工厂类 - 具体工厂
 * @Author 柳成荫
 * @Date 2019年9月21日
 * @Version V1.0.0
 */
public class FileLogFactory implements LogFactory {

	@Override
	public Log createLog() {
		return new FileLog();
	}

}
/**
 * 
 * @ClassName DatabaseLogFactory
 * @Description 数据库日志记录工厂类 - 具体工厂
 * @Author 柳成荫
 * @Date 2019年9月21日
 * @Version V1.0.0
 */
public class DatabaseLogFactory implements LogFactory {

	@Override
	public Log createLog() {
		return new DatabaseLog();
	}

}
/**
 * 
 * @ClassName Client
 * @Description 客户端测试类
 * @Author 柳成荫
 * @Date 2019年9月21日
 * @Version V1.0.0
 */
public class Client {

	public static void main(String[] args) {
		LogFactory logFactory;
		Log log;
		logFactory = new FileLogFactory();
		log = logFactory.createLog();
		log.writeLog();
	}

}

 

优点

1.用户只需关心产品对应的工厂,无需关心创建细节,甚至无需知道具体产品类的类名。

2.让工厂自主确定创建何种产品对象,而如何创建这个对象的细节完全封装在具体工厂内部。

3.系统中加入新产品时无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,只需要添加一个具体的工厂和具体的产品即可。系统的可扩展性非常好,完全符合开闭原则。

缺点

1.添加新产品时,需要编写新的具体产品类和具体的工厂,导致系统中类的个数成对增加。在一定程度上增加了系统的复杂性,有更多的类需要编译和运行,给系统增加了一些额外的开销。

2.需要使用抽象层进行定义,增加了系统的抽象性和理解难度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值