1.定义:
b.工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
c.在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
2.工厂方法模式的通用类图:
在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂 ConcreteCreator完成的。
3.工厂方法模式的例子:
3-1.创建抽象产品类Product:
public abstract class Product {
//产品类的公共方法
public void method1() {
//业务逻辑处理
}
//抽象方法
public abstract void method2();
}
3-2.创建具体产品类ConcreteProduct(可以有多个,但需继承于抽象产品类):
public class ConcreteProduct extends Product {
public void method2() {
//业务逻辑处理
}
}
3-3.创建抽象工厂类Creator(负责定义产品对象的产生):
public abstract class Creator {
/**
* 创建一个产品对象,其输入参数类型可以自行设置
* 通常为String、Enum、Class等,当然也可以为空
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
3-4.创建具体工厂类ConcreteCreator(具体如何产生一个产品的对象,是由具体的工厂类实现的):
public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c) {
Product product = NULL;
try {
product = (Product) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// 异常处理
}
return (T) product;
}
}
3-5.创建场景类Client:
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/** 继续业务处理 */
}
}
4.工厂方法模式的优点:
1、良好的封装性,代码结构清晰,一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品类,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化。
4、工厂方法模式是典型的解耦框架。高层模块值需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特法则,我不需要的就不要去交流;也符合依赖倒置原则,只依赖产品类的抽象;当然也符合里氏替换原则,使用产品子类替换产品父类
5.工厂方法模式的缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
6.工厂方法模式的几个使用场景:
1、工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重地考虑是否要增加一个工厂类进行管理,增加代码的复杂度;其次,需要灵活的、可扩展的框架时,可以考虑采用工厂方法模式;再次,工厂方法模式可以用在异构项目中,最后,可以使用在测试驱动开发的框架下。诸如以下场景:
2、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
3、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
4、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
7.工厂方法模式的注意事项:
作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。