设计模式-工厂模式

141 阅读2分钟

Factory Method

1. 模型定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类

类图:

image.png

应用场景

  • 当你不知道所使用对象的确切类型时
  • 当你希望为库或框架提供扩展其内部组件的方法时

优点

  • 将具体产品和创建者解耦
  • 符合单一职责原则
  • 符合开闭原则

源码中的应用

// 工厂方法
// 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;
    }
}
  1. 将类中稳定不变的部分进行抽离,封装成抽象接口
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具体的类

  1. 简单工厂

并不是一个设计模式,只是一种编码技巧

创建一个类,通过不同参数进行不同对象的创建:

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;
    }
}
  1. 工厂模式 将应用变为抽象类,将实际创建的方法变成抽象方法,让用户在子类中进行实现。
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();
    }
}