工厂方法是一种创建型生产模式。在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。
理解
按照我的理解,工厂方法主要的意图是隐藏new方法,封装对象的创建方法,让使用者更关注对象本身,而不是如何创建这个对象。接下来我们用筷子生产线的例子来感受一下工厂方法。
筷子生产线
定义产品接口
首先我们定义一下产品的接口,也就是筷子
/**
* @author wangxing
*/
public interface Chopsticks {
/**
* 使用
*/
void use();
/**
* 回收
*/
void recycle();
}
定义工厂接口
然后我们定义一下筷子的工厂
/**
* 筷子工厂
* @author wangxing
*/
public interface ChopsticksFactory {
/**
* 生产筷子
*
* @param user 筷子的使用者
* @return 筷子
*/
Chopsticks create(String user);
}
定义具体的工厂和产品
竹筷子工厂和竹筷子
/**
* 竹筷子
*
* @author wangxing
*/
public class BambooChopsticks implements Chopsticks {
@Override
public void use() {
System.out.println("从塑料袋里拿出来,掰开,夹菜");
}
@Override
public void recycle() {
System.out.println("扔掉");
}
}
因为竹筷子是一次性的,所以每次都直接new出来一个新的竹筷子
/**
* 竹筷子工厂
* @author wangxing
*/
public class BambooChopsticksFactory implements ChopsticksFactory{
@Override
public Chopsticks create(String user) {
System.out.println(user+"来了,给他一双一次性筷子");
return new BambooChopsticks();
}
}
木筷子工厂和木筷子
/**
* 木头筷子
*
* @author wangxing
*/
public class WoodChopsticks implements Chopsticks {
@Override
public void use() {
System.out.println("从饭盒里拿出来,夹菜");
}
@Override
public void recycle() {
System.out.println("洗干净,放回到饭盒里");
}
}
一般木筷子都是反复使用的,所以不会每次都new新的筷子,而是先看缓存里是否有筷子了,没有筷子再new筷子,有筷子时就直接取出筷子。
/**
* 木筷子工厂
*
* @author wangxing
*/
public class WoodChopsticksFactory implements ChopsticksFactory {
private static final ConcurrentHashMap<String, Chopsticks> cache = new ConcurrentHashMap<>();
@Override
public Chopsticks create(String user) {
System.out.println(user + "来了,把属于他的那双筷子给他了");
return cache.computeIfAbsent(user, (k) -> new WoodChopsticks());
}
}
使用工厂
-
大家都使用一次性筷子
public class Main { public static void main(String[] args) { String[] users = {"张三", "李四", "王五", "赵柳", "二麻子"}; ChopsticksFactory chopsticksFactory = new BambooChopsticksFactory(); for (String user : users) { Chopsticks chopsticks = chopsticksFactory.create(user); chopsticks.use(); chopsticks.recycle(); } } }
-
大家都使用木筷子
public class Main { public static void main(String[] args) { String[] users = {"张三", "李四", "王五", "赵柳", "二麻子"}; ChopsticksFactory chopsticksFactory = new WoodChopsticksFactory(); for (String user : users) { Chopsticks chopsticks = chopsticksFactory.create(user); chopsticks.use(); chopsticks.recycle(); } } }
工厂方法
- 会到头来,我们再体会一下什么是工厂方法。在上面的例子中工厂方法说的就是
ChopsticksFactory#create
,ChopsticksFactory
作为工厂,定义了什么是筷子(Chopsticks
)以及要干什么(create
)。具体要如何生产、生产出什么样的筷子,都是子类(BambooChopsticksFactory
,WoodChopsticksFactory
)来决定的。所以才会有工厂方法使一个类的实例化延迟到子类的说法。 - 同时,因为使用工厂方法封装了对象new的过程,所以我们可以控制对象的创建。比如竹筷子是一次性的,那我们就每次都new一个新的出来。但是木筷子是循环使用的,所以我们采用缓存的方式将对象缓存起来。