设计模式 之 工厂模式

一、介绍

今天,我们来回顾一下工厂方法模式,这个模式很简单。

《研磨设计模式》中的定义是:定义一个用于创建对象的接口,让子类决定实例化哪个类,“Factory Mehod”使一个类的实例化延迟到子类。

工厂方法模式的本质是——延迟到子类来选择实现

什么意思呢?简单来说,就是面向接口编程。

打个比方,我现在需要一个水果类,就可以直接写一个简单的水果接口 interface Fruit{},至于实现类是什么,我不关心。直接使用这个接口就是了,反正java对象是运行时绑定。怎么使用这个接口呢,当然是抽象方法了。这样,不同的子类继承的时候就可以选择不同的实现类。

二、结构

1、Product——需要创建的对象的接口。

2、ConcreteProduct——需要创建的对象的实现类。

3、Creator——工厂方法接口,有一个返回所需对象的抽象方法,留给子类选择实现。也可以提供默认的实现。

4、ConcreteCreator——工厂方法实现类。用来提供具体的选择实现。

三、我的实现

1、首先我们有一个简单的产品接口和它的2个实现,如下:

package factoryMethod;

public interface Product {

    public void autoFly();
}
package factoryMethod;

public class ProductImpl1 implements Product{

    public void autoFly() {
        // TODO Auto-generated method stub
        System.out.println("product1 is flying!");
    }

}
package factoryMethod;

public class ProductImpl2 implements Product{

    public void autoFly() {
        // TODO Auto-generated method stub
        System.out.println("product2 is flying!");
    }

}

2、我们建立了一个工厂,使用这个工厂,就可以实现产品的功能。

package factoryMethod;

public abstract class MyFactory {

    protected abstract Product getMyProduct();
    
    public void fly(){
        getMyProduct().autoFly();
    }
}

如上,我们编写的这个工厂为一个抽象类,我们不知道它的具体实现,但是它已经完成了逻辑调用。它的具体调用,留到子类去实现。

3、那么我们编写2个工厂子类,如下:

package factoryMethod;

public class Factory1 extends MyFactory {

    @Override
    protected Product getMyProduct() {
        // TODO Auto-generated method stub
        return new ProductImpl1();
    }

}
package factoryMethod;

public class Factory2 extends MyFactory {

    @Override
    protected Product getMyProduct() {
        // TODO Auto-generated method stub
        return new ProductImpl2();
    }

}

如上,工厂的子类只需要实现父类没有完成功能,而无需改变父类的基本功能。

4、那么客户端调用如下:

package factoryMethod;

public class Client {

    public static void main(String[] args) {
        MyFactory factory = new Factory1();
        factory.fly();
    }
}

如上,我们是直接通过工厂来调用产品功能,工厂本身并不负责选择实现。选择实现是简单工厂模式的本质。

我们可以看到,工厂方法模式是通过工厂类简单的抽象来实现的。

如果我们需要创建某个接口的对象,但是又不知道具体的实现,那么我们可以使用工厂方法模式。

5、另外,工厂方法模式还有另一种用法,那就是工厂类本身有默认的实现,这种情况下,工厂类可以构造为普通类,而不是抽象类。如下:

package factoryMethod;

public class NewFactory {

    protected Product getMyProduct() {
        // TODO Auto-generated method stub
        return new ProductImpl1();
    }

    public void fly() {
        getMyProduct().autoFly();
    }
}

6、然后,当我们需要另一个产品的时候,就可以继承NewFactory,重写getMyProduct()方法,如下:

package factoryMethod;

public class SonOfNewFacory1 extends NewFactory{

    @Override
    protected Product getMyProduct() {
        // TODO Auto-generated method stub
        return new ProductImpl2();
    }
}

客户端调用就毋须演示了。

7、同样,工厂方法模式可以与简单工厂模式结合起来,在工厂方法模式中选择实现。如下:

package factoryMethod;

public class FunctionFactory {

    protected Product getMyProduct(int type) {
        Product product = null;
        if (type == 1) {
            product = new ProductImpl1();
        } else {
            product = new ProductImpl2();
        }
        return product;
    }

    public void fly(int type) {
        getMyProduct(type).autoFly();
    }
}

8、如果需要添加一个新的实现,《研磨设计模式》中提到了一种优雅的方式,如下:

package factoryMethod;

public class SonOfFunctionFactory1 extends FunctionFactory {

    @Override
    protected Product getMyProduct(int type) {
        // TODO Auto-generated method stub
        if (type == 3) {
            return new ProductImpl3();
        }
        //其他的让父类去实现
        return super.getMyProduct(type);
    }
}
原文地址:https://www.cnblogs.com/JiangWJ/p/10801238.html