1.面对的问题
简单工厂模式当新增一个新的对象类型时,是需要修改工厂代码的,违反了开闭原则。
简单工厂模式:先写一个工厂类,再写一个抽象方法类,最后通过具体产品类创建产品
为了弥补这个问题,我们引入了工厂方法模式。
2.工厂方法模式:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类
先定义一个抽象的工厂类,再定义具体的工厂类来生产产品,这些产品实现了抽象工厂类中声明的方法。
当需要新增一个类型,只需要新增一个具体的工厂类就可以了。
工厂方法模式和简单工厂模式区别:工厂方法不再提供一个统一的工厂类创建所有产品对象,而是针对不同的产品提供不同的工厂。
3.工厂方法模式结构
工厂方法模式提供了一个抽象工厂接口来声明抽象工厂方法,而由其子类来具体实现工厂方法,创建具体的产品对象
1)product(抽象产品)
它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类
2)ConcreteProduct(具体产品)
它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品一一对应
3)Factory(抽象工厂)
在抽象工厂类中声明了工厂方法,用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口
4)ConcreteFactory(具体工厂)
它是抽象工厂的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例
(具体产品需要实现抽象产品)
4.工厂方法模式的实现
1)先创建抽象产品类
package controller.factoryModule;
/**
*抽象产品
*/
public interface Product {
public void getProduct();
}
2)创建具体产品类A、B
package controller.factoryModule;
public class ConcreteProductA implements Product {
@Override
public void getProduct() {
System.out.println("具体产品A");
}
}
package controller.factoryModule;
public class ConcreteProductB implements Product {
@Override
public void getProduct() {
System.out.println("具体产品B");
}
}
3)创建抽象工厂类
package controller.factoryModule;
import controller.factoryModule.Product;
public interface Factory {
public Product factoryMethod();
}
4)具体工厂A、B
package controller.factoryModule;
public class ConcreteFactoryA implements Factory {
@Override
public ConcreteProductA factoryMethod() {
return new ConcreteProductA();
}
}
package controller.factoryModule;
public class ConcreteFactoryB implements Factory {
@Override
public ConcreteProductB factoryMethod() {
return new ConcreteProductB();
}
}
5)客户端调用
package controller.factoryModule;
public class Client {
public static void main(String[] args) {
Factory factory;
factory = new ConcreteFactoryA();
Product product;
product = factory.factoryMethod();
product.getProduct();
}
}
5.反射机制与配置文件
设计模式上述已经讲完,但是我们在代码里new了工厂,在生产时随着环境的切换,我们需要通过反射+配置文件来创建而不是通过new。
1)反射创建类
//根据类名获取类
Class A = Class.forName("java.lang.String");
Object obj = A.newInstance();
6.工厂方法的重载
工厂接口可以给出同样的接口名但是不一样的参数来实现重载
7.工厂模式优缺点
优:
弥补了简单工厂的新增产品类型需要动工厂代码的问题
缺:
增加复杂性