工厂模式
定义:
定义一个创建对象的接口,让子类决定实例化哪个类
使用场景
需要生成复杂对象的就可以使用工厂模式,简单对象直接new即可
工厂模式写法
UML图如下:
实例来源:http://liuwangshu.cn/designpatterns/10-factorymethod.html
所需者有四种角色:
- 抽象产品类:Computer
- 具体产品类:LenovoComputer、HpComputer、AsusComputer实现Computer接口
- 抽象工厂类:ComputerFactory
具体工厂类:GDComputerFactory
创建抽象产品类
//抽象产品类,抽象方法用于启动
public abstract class Computer {
public abstract void start();
}
创建具体产品类
public class LenovoComputer extends Computer{
@Override
public void start() {
System.out.println("联想电脑启动");
}
}
public class HpComputer extends Computer{
@Override
public void start() {
System.out.println("惠普电脑启动");
}
}
public class AsusComputer extends Computer{
@Override
public void start() {
System.out.println("华硕电脑启动");
}
}
创建抽象工厂类
//抽象工厂类,抽象方法用于创建具体产品
public abstract class ComputerFactory {
public abstract <T extends Computer>T createComputer(Class<T> clz);
}
创建具体工厂类
/**
这里是使用反射的方式来生成具体产品类,也可以针对每一个具体产品创建具体的工厂
类,这种叫做多工厂方法模式。当然工厂类也可以写成一个简单的静态工程类
*/
public class GDSComputerFactory extends ComputerFactory{
@Override
public <T extends Computer> T createComputer(Class<T> clz) {
Computer computer = null;
String classname = clz.getName();
try {
//反射获取要创建的产品类
computer = (Computer) Class.forName(classname).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T)computer;
}
}
客户端调用
public class Client {
public static void main(String[]args) {
ComputerFactory computerFactory = new GDComputerFactor();
LenovoComputer mLenovoComputer=computerFactory.createComputer(LenovoComputer.class);
mLenovoComputer.start();
HpComputer mHpComputer=computerFactory.createComputer(HpComputer.class);
mHpComputer.start();
AsusComputer mAsusComputerr=computerFactory.createComputer(AsusComputer.class);
mAsusComputerr.start();
}
}
这里我们可以看出其实工厂模式的本质就是实现对象的调用和创建分离,调用者不必关心对象的创建过程,降低耦合度。这种模式其实很常见,比如我们都用过线程池,跟进源码如下:
Executors源码
/**
每一个方法中都是new了一个ThreadPoolExecutor,这才是真正的线程池,它里面有很
多个参数我们可以进行配置,但是有时候我们根本不用自己去配置,直接到
Executors工厂类中选择一种我们需要的线程池就可以了!省去了复杂的配置过程!这就是Android系统中的工厂模式的体现
*/
public class Executors {
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
.......