java的工厂模式是开发中和常见的方法,而且也是spring中比较重要的模式之一。
工厂模式常见的分类为三种:简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)
感觉有个背景可能好理解一点,所以简单举个栗子:假设联合国现在需要
士兵参加维和任务,中国和英国同时要派士兵参加。ok,现在让我们看看java怎么来实现这步操作。
先创建一个士兵的接口:
public interface Soldier {
public void nationality ();
}
创建不同国家士兵的实现类:
public class ChineseSoldier implements Soldier{
@Override
public void nationality(){
System.out.println("ChineseSoldier");
}
}
public class BritishSolider implements Soldier {
@Override
public void nationality(){
System.out.println("BritishSoldier");
}
}
最后来创建工厂类:
public class CreateSoldier {
public Soldier create (String str){
if("china".equals(str)){
return new ChineseSoldier();
}else if("british".equals(str)){
return new BritishSolider();
}else{
System.out.println("error");
return null;
}
}
}
来测试一下:
public static void main(String[] args) {
CreateSoldier cs = new CreateSoldier();
Soldier soldier = cs.create("china");
soldier.nationality();
}
输出:ChineseSoldier
很明显在简单工厂模式里面,如果我们传递的字符串出错了,那整个工厂就瘫痪啦,不知道要派哪个国家的士兵,出现背锅现象。所以为了避免这种情况,我们对上面的代码稍微改动一下就可以升级成工厂方法模式。
士兵的接口:
public interface Soldier {
public void nationality ();
}
不同国家士兵的实现类:
public class ChineseSoldier implements Soldier{
@Override
public void nationality(){
System.out.println("ChineseSoldier");
}
}
public class BritishSolider implements Soldier {
@Override
public void nationality(){
System.out.println("BritishSoldier");
}
}
重新实现工厂类:
public class CreateSoldier {
public static Soldier createbrisoldier (){
return new BritishSolider();
}
public static Soldier createchisoldier(){
return new ChineseSoldier();
}
}
再来测试一下:
public static void main(String[] args) {
Soldier soldier = CreateSoldier.createchisoldier();
soldier.nationality();
}
输出:ChineseSoldier
其实你肯定也能发现工厂方法模式有个很大的问题就是,类的创建(也就是栗子中士兵的产生)太依赖工厂了,换言之,如果你想拓展程序,就必须对工厂类进行修改(简单点说就是,现在联合国需要派遣美国士兵,但是很明显soldier工厂只能生产中国和英国士兵,所以现在就必须重新再盖一个能生产美国士兵的工厂,所以这既繁琐,又浪费资源)。说的专业点哈,就是违背了闭包原则。So,抽象工厂模式就理所应当的被设计出了。提供一个共同的工厂接口,创建多个工厂类,这样一旦增加新需求,直接增加新的工厂类就好了。
继续上面的栗子
士兵的接口:
public interface Soldier {
public void nationality ();
}
不同国家士兵的实现类:
public class ChineseSoldier implements Soldier{
@Override
public void nationality(){
System.out.println("ChineseSoldier");
}
}
public class BritishSolider implements Soldier {
@Override
public void nationality(){
System.out.println("BritishSoldier");
}
}
定义工厂接口:
public interface CreateSoldier {
public Soldier create();
}
实现不同工厂类:
public class CreateBriSoldier implements CreateSoldier {
@Override
public Soldier create() {
return new BritishSolider();
}
}
public class CreateChiSoldier implements CreateSoldier {
@Override
public Soldier create() {
return new ChineseSoldier();
}
}
Ok我们再来测试一下:
public static void main(String[] args) {
CreateSoldier cs = new CreateChiSoldier();
Soldier soldier = cs.create();
soldier.nationality();
}
输出:ChineseSoldier
抽象工厂模式的好处就是,针对不同的需求,对于同一个接口,我们就只需要去实现不同的工厂类就行了。