1、定义、使用场景
定义一个用于创建对象的接口,让子类决定实例化那个类。在需要生成复杂对象的地方,都可以使用工厂方法模式。
概念总是抽象的,下面从代码的角度去理解。
2、实现
工厂方法模式一般有四大模块:
- 抽象产品类,工厂方法所创建的产品的父类
- 具体的产品类,实现了抽象产品类的具体产品
- 抽象工厂类,工厂方法模式的核心
- 具体的工厂类,实现具体的产品生产业务逻辑
接下来按照这四个模块来实现工厂方法模式。
先举个栗子,对于水果7和水果7plus来说除了基本的共性外,相对明显的差别就是水果7plus是双摄像头和大尺寸。
所以首先声明一个抽象的产品类:
public abstract class Iphone {
public abstract void camera();
public abstract void screen();
}
接下来就是具体的产品类:
public class Iphone7 extends Iphone {
@Override
public void camera() {
Log.e("Iphone7", "Iphone7的单摄");
}
@Override
public void screen() {
Log.e("Iphone7", "Iphone7的4.7寸屏幕");
}
}
public class Iphone7Plus extends Iphone {
@Override
public void camera() {
Log.e("Iphone7Plus", "Iphone7Plus的双摄");
}
@Override
public void screen() {
Log.e("Iphone7Plus", "Iphone7Plus的5.5寸屏幕");
}
}
产品定义好了,就需要工厂生产了,当然要先定义一个抽象的工厂类:
public abstract class IphoneFactory {
public abstract <T extends Iphone> T createPhone(Class<T> clz);
}
接下来就是具体的工厂类:
public class NewIphoneFactory extends IphoneFactory {
@Override
public <T extends Iphone> T createPhone(Class<T> clz) {
Iphone iphone = null;
try {
iphone = (Iphone) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) iphone;
}
}
到这里一个工厂方法模式就搭建出来了,测试下吧:
public class Client {
public static void test() {
NewIphoneFactory factory = new NewIphoneFactory();
Iphone7 iphone7 = factory.createPhone(Iphone7.class);
iphone7.camera();
iphone7.screen();
Iphone7Plus iphone7Plus = factory.createPhone(Iphone7Plus.class);
iphone7Plus.camera();
iphone7Plus.screen();
}
}
结果如下:
3、工厂类的其它实现
前边我们工厂中通过反射方式构建出产品,需要那个类的对象,传入哪个类的类型即可,除了这种方式外我们还可以有别的选择:为每个产品都定义一个具体的工厂类,之间相互隔离。
首先对抽象工厂类做如下修改:
public abstract class IphoneFactory {
public abstract Iphone createPhone();
}
然后是具体的工厂类:
public class Iphone7Factory extends IphoneFactory {
@Override
public Iphone createPhone() {
return new Iphone7();
}
}
public class Iphone7PlusFactory extends IphoneFactory {
@Override
public Iphone createPhone() {
return new Iphone7Plus();
}
}
当然调用时就需要创建两个工厂类对象了,我们可以称之为多工厂方法模式。
当我们只有一个工厂类时,可以考虑简化掉抽象工厂类,直接在具体的工厂类中使用静态方法,如下:
public class IphoneFactory {
public static Iphone createPhone() {
return new Iphone7Plus();
}
}
4、小结
工厂方法模式采用抽象的架构,将具体的任务交给子类去完成,方便扩展,同时降低了耦合。当然缺点也是有的,例如需要添加新的产品时就要编写一个产品类,还要引入抽象类,导致代码结构变复杂。所以使用时就需要根据具体的场景去权衡了。