工厂方法的定义:Define a interface for creating an object, but let subclass decide which class to instantiate. Factory method let a class defer instantiation to subclass.
工厂方法模式是一个比较简单易于理解的设计模式。它主要涉及两方面:工厂,也就是对象或者产品的创建者;另一部分是被创建的对象,或者说是产品。我们看看工厂方法的类图:
在工厂方法模式中,抽象类Factory并不负责具体创建产品的细节,具体的细节在其实现类,也就是具体的工厂中给出。同样,抽象类Product也只是定义了产品之间的共性,也就是对这一类事物的抽象。具体不同的产品细节是不同的。下面我们以农场种植水果为例,说明这个设计模式。
我们知道,农场可以种植苹果、梨子、香蕉……在这个例子中,农场就是工厂方法模式中的工厂,苹果、梨子、香蕉就是工厂创建出来的各种产品。我们先定义抽象的工厂类Farm,如下:
package dp.factorymethod; public abstract class Farm<T extends Fruit> { public abstract T plantFruit(Class<T> c); }
在这个类中,我们只定义了一个抽象方法,也就是规定农场种植水果。接下来我们定义水果Fruit,我们可以定义一个接口:
package dp.factorymethod; public interface Fruit { public void getColor(); public void getTaste(); }
在Fruit接口中,我们定义了两个水果的共性,具有颜色和味道(口感)。在抽象工厂类中,我们使用了泛型,也就是说,农场生产的是任何一种水果,换句话说,任何一个实现了Fruit接口的类的实例。有了抽象工厂类和产品接口,接下来我们需要定义一个具体的工厂(农场)和几个具体的产品(水果)。
对于具体工厂类,比如说,我们取个恶俗的名字,RedStarFarm(红星农场),其代码如下:
package dp.factorymethod; public class RedStarFarm extends Farm{ @Override public <T extends Fruit> T plantFruit(Class<T> clazz) { Fruit fruit = null; try { fruit = (Fruit) Class.forName(clazz.getName()).newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T) fruit; } }
再分别定义苹果Apple、香蕉Banana的代码:
package dp.factorymethod; public class Apple implements Fruit { @Override public void getColor() { System.out.println("红色的"); } @Override public void getTaste() { System.out.println("酸酸甜甜的"); } }
package dp.factorymethod; public class Banana implements Fruit { @Override public void getColor() { System.out.println("黄色的"); } @Override public void getTaste() { System.out.println("甜的软软的"); } }
工厂方法模式的几部分内容都有了,下面就差写一个Client程序了:
package dp.factorymethod; public class Client { public static void main(String[] args) { Farm farm = new RedStarFarm(); Fruit apple = farm.plantFruit(Apple.class); System.out.println("Apple:"); apple.getColor(); apple.getTaste(); Fruit banana = farm.plantFruit(Banana.class); System.out.println("Banana:"); banana.getColor(); banana.getTaste(); } }
运行一下程序,输出:
以上就是工厂方法模式。