工厂方法(Factory Method)
和简单工厂方模式的不同之处在于,工厂方法把工厂类也抽象出来一个接口(抽象类),每一种产品都有自己对应的工厂类。
前面就说到了简单工厂模式,现在设想一下,如果我们新出一款产品iphone13,需要怎么改动代码。
1)首先我们要创建一个新的手机产品类Iphone13实现Apple接口
2)在工厂类修改代码,加上新手机的逻辑代码。
我在这里举得代码是十分简单的,但在实际项目是十分复杂(层次深)的结构。所以在工厂类修改代码会很冗杂。
这时候工厂模式来了!它来了!把工厂类定义成接口,每新增一款产品就实现Apple接口,再创建一个对应的工厂类实现工厂接口。这样的设计就可以实现扩展,不用去修改原来的代码。美滋滋。
/**
* 苹果系列
*/
public interface Apple {
}
public class Iphone12 implements Apple {
}
public class Iphone11 implements Apple {
}
public class Iphone10 implements Apple {
}
工厂类:
/**
* 工厂类
*/
public interface AppleFactory {
public Apple createPhone();
}
public class Iphone12Factory implements AppleFactory {
public Apple createPhone(){
return new Iphone12();
}
}
public class Iphone11Factory implements AppleFactory {
public Apple createPhone(){
return new Iphone11();
}
}
public class Iphone10Factory implements AppleFactory {
public Apple createPhone(){
return new Iphone10();
}
}
客户类:
public class Consumer {
public static void main(String[] args) {
Factory iphone12Factory = new Iphone12Factory();
Apple iphone12 = iphone12Factory.createPhone();
//这里我们需要什么产品类,用对应工厂类的createPhone()方法即可
Factory iphone11Factory = new Iphone11Factory();
Apple iphone11 = iphone11Factory.createPhone();
}
}
我这里先说明,并不是哪个设计模式就一定是最好的。用哪个模式还是得根据实际项目的情况来。
尽管工厂模式的扩展性强,新增产品类不必修改源代码,但当产品种类很多时,就会出现大量的工厂类。我们可以考虑简单工厂模式和工厂方法模式结合的方式使用。
Expand(一个更妙的工厂模式)
看完上面的工厂模式,再来看看另外一个。看完这个我相信你对工厂模式的认识会更近一层楼。
产品类:同上(略)
工厂类:
/**
* 工厂类
*/
public abstract AppleFactory {
public abstract Apple createPhone();
public void doSomething(){
Apple iphone = createPhone();
//I have to do something
}
}
public class Iphone12Factory implements AppleFactory {
public Apple createPhone(){
return new Iphone12();
}
}
public class Iphone11Factory implements AppleFactory {
public Apple createPhone(){
return new Iphone11();
}
}
public class Iphone10Factory implements AppleFactory {
public Apple createPhone(){
return new Iphone10();
}
}
客户类:
public class Consumer {
public static void main(String[] args) {
Factory iphone12Factory = new Iphone12Factory();
iphone12Factory.doSomething();
}
}
可以看出,工厂模式是一种设计思想,并不限制你的工厂父类是接口还是抽象类。它只关心你是如何实现(工厂模式是每个产品对应一个工厂)。
这两种实现其实并没有多大差别,后者并不直接返回一个产品对象,而是使用这个对象去做一些事。我举个栗子,我拿到手机第一时间就把它送给别人,其他的不关心。这时候doSomething()就是送给别人。