Factory Method
1. 模型定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类
类图:
应用场景
- 当你不知道所使用对象的确切类型时
- 当你希望为库或框架提供扩展其内部组件的方法时
优点
- 将具体产品和创建者解耦
- 符合单一职责原则
- 符合开闭原则
源码中的应用
// 工厂方法
// java.net.URLStreamHandleFactory
public interface URLStreamHandlerFactory {
/**
* Creates a new {@code URLStreamHandler} instance with the specified
* protocol.
*
* @param protocol the protocol ("{@code ftp}",
* "{@code http}", "{@code nntp}", etc.).
* @return a {@code URLStreamHandler} for the specific protocol.
* @see java.net.URLStreamHandler
*/
URLStreamHandler createURLStreamHandler(String protocol);
}
// 子类实现
private static class Factory implements URLStreamHandlerFactory {
private static String PREFIX = "sun.net.www.protocol";
private Factory() {
}
public URLStreamHandler createURLStreamHandler(String var1) {
String var2 = PREFIX + "." + var1 + ".Handler";
try {
Class var3 = Class.forName(var2);
return (URLStreamHandler)var3.newInstance();
} catch (ReflectiveOperationException var4) {
throw new InternalError("could not load " + var1 + "system protocol handler", var4);
}
}
}
2. 代码重构
原始代码:
public class FactoryMethod {
public static void main(String[] args) {
Application application = new Application();
ProductA product = application.getObject();
product.method1();
}
}
class ProductA {
public void method1() {
System.out.println("ProductA==>method1==>executed");
}
}
class Application {
private ProductA createProduct() {
return new ProductA();
}
ProductA getObject() {
ProductA product = createProduct();
return product;
}
}
- 将类中稳定不变的部分进行抽离,封装成抽象接口
interface Product {
/**
* 抽象方法
*/
public void method1();
}
class ProductA implements Product{
@Override
public void method1() {
System.out.println("ProductA==>method1==>executed");
}
}
对应的在使用的时候可以使用接口类来进行接收:
class Application {
private Product createProduct() {
return new ProductA();
}
Product getObject() {
Product product = createProduct();
return product;
}
}
缺点:在创建对象的时候,还不能避免
new具体的类
- 简单工厂
并不是一个设计模式,只是一种编码技巧
创建一个类,通过不同参数进行不同对象的创建:
class SimpleFactory {
public static Product createProduct(String type) {
if (type.equals("0")) {
return new ProductA();
} else if ("1".equals(type)){
return new ProductB();
} else {
return null;
}
}
}
这样在具体使用的时候就可以通过参数来控制创建对象,代码就不会写死具体new某一个类:
class Application {
private Product createProduct(String type) {
return SimpleFactory.createProduct(type);
}
Product getObject(String type) {
Product product = createProduct(type);
return product;
}
}
- 工厂模式 将应用变为抽象类,将实际创建的方法变成抽象方法,让用户在子类中进行实现。
abstract class Application {
/**
* 抽象方法
* @return
*/
abstract Product createProduct();
Product getObject() {
Product product = createProduct();
return product;
}
}
子类实现:
class ConcreateProductA extends Application {
@Override
Product createProduct() {
return new ProductA();
}
}
class ConcreateProductB extends Application {
@Override
Product createProduct() {
return new ProductB();
}
}
具体使用:
public class FactoryMethod {
public static void main(String[] args) {
Application application = new ConcreateProductB();
Product product = application.getObject();
product.method1();
}
}
3. 整体代码
public class FactoryMethod {
public static void main(String[] args) {
Application application = new ConcreateProductB();
Product product = application.getObject();
product.method1();
}
}
interface Product {
/**
* 抽象方法
*/
public void method1();
}
class ProductA implements Product{
@Override
public void method1() {
System.out.println("ProductA==>method1==>executed");
}
}
class ProductB implements Product{
@Override
public void method1() {
System.out.println("ProductB==>method1==>executed");
}
}
abstract class Application {
/**
* 抽象方法
* @return
*/
abstract Product createProduct();
Product getObject() {
Product product = createProduct();
return product;
}
}
class ConcreateProductA extends Application {
@Override
Product createProduct() {
return new ProductA();
}
}
class ConcreateProductB extends Application {
@Override
Product createProduct() {
return new ProductB();
}
}